2013-05-14 139 views
2

我正在寻找一种密码保护PDF文件的方式,无需以明文形式存储用户密码。在不影响密码的情况下即时密码保护PDF文档

我想要做的是根据PDF规范生成用户和所有者密钥,并使用它们来加密文档的字符串和流。有支持这种功能的库吗?

- 编辑 -

只是为了澄清,我想要做的就是让用户输入自己的密码进入系统一次,然后任何时间后,为了能够到PDF文件与加密从该密码生成的密钥。大多数PDF库要求密码以明文形式传递,我想要的是一个采用“公共”密钥的加密函数。

+0

什么使你*不得不以明文存储用户的密码?* – mkl 2013-05-14 05:09:48

+0

@mkl我使用的命令行工具(qpdf)只提供明文密码的选项。 – 2013-05-14 06:10:02

+0

在加密过程中的某个步骤中,即使只在内存中,密码仍以纯文本形式存在。如果没关系,任何像样的通用PDF库都可以。在运行时环境或lib的许可细节方面是否有任何限制? – mkl 2013-05-14 07:33:33

回答

0

http://itextpdf.com/拥有包含加密功能的开源Java和C#PDF库。

+0

谢谢。我看了一下Java源代码。它可能会被修改为做我想要的。 – 2013-05-14 06:09:32

0

几乎每个PDF库都支持PDF加密。

用户和所有者密码以完全相同的方式存储在加密的PDF中。这是必要条件,因为它是由规范定义的。

因此,就图书馆而言,你将发现的差异将与支持的加密方案有关,而不是密码的实际存储。

大部分将支持旧的基本形式。很少支持AES 256位加密。这只取决于对你重要的事情。

我在ABCpdf .NET软件组件上工作,所以我的回复可能包含基于ABCpdf的概念。这正是我所知道的。 :-)”

+0

我不会说实际上每个PDF库都支持它。例如,我惊讶地发现Perl中的两个主要PDF库(CAM :: PDF和PDF :: API2)不支持OP所要做的事情,即加密由另一个程序创建的未加密的PDF 。如果你看一下PDF规范,它的明显原因,绝对不是微不足道的添加到图书馆。 – qwwqwwq 2013-05-14 14:22:00

0

我想我已经找到了qpdf源的答案

libqpdf/qpdfencryption.cc线999:

if (V < 5) 
{ 
    // For V < 5, the user password is encrypted with the owner 
    // password, and the user password is always used for 
    // computing the encryption key. 
    this->encryption_key = compute_encryption_key(
     this->user_password, data); 
} 
else 
{ 
    // For V >= 5, either password can be used independently to 
    // compute the encryption key, and neither password can be 
    // used to recover the other. 
    bool perms_valid; 
    this->encryption_key = recover_encryption_key_with_password(
     this->provided_password, data, perms_valid); 
    if (! perms_valid) 
    { 
     warn(QPDFExc(qpdf_e_damaged_pdf, this->file->getName(), 
        "encryption dictionary", this->file->getLastOffset(), 
        "/Perms field in encryption dictionary" 
        " doesn't match expected value")); 
    } 
} 

无论哪种方式,需要密码来计算。加密密钥我怀疑是计算加密密钥都可能会受到逆向工程来恢复密码,让存储,这也是一个不错的主意

我能想到的方案是:

  1. 要求用户每次下载文件时都要重新输入密码。
  2. 为每个用户提供安全性较低的二级密码 - 仅用于加密PDF文件。确保它与用户的主密码不同。

我开始认为使用用户的主密码保护PDF文件可能会造成安全漏洞。我要#2。