在不影响密码的情况下动态保护PDF文档

在不影响密码的情况下动态保护PDF文档,pdf,encryption,Pdf,Encryption,我正在寻找一种方法来动态地对PDF文件进行密码保护,而不必以明文形式存储用户密码 我想做的是根据PDF规范生成用户和所有者密钥,并使用它们来加密文档的字符串和流。是否有支持此功能的库 --编辑-- 我只是想澄清一下,我想做的是允许用户在系统中输入密码一次,然后在这之后的任何时候都可以使用该密码生成的密钥对PDF文件进行加密。大多数PDF库都要求以明文形式传递密码,我想要的是一个接受“公共”密钥的加密函数。有包含加密的开源Java和C#PDF库。几乎每个PDF库都支持PDF加密 每个库以完全相同的

我正在寻找一种方法来动态地对PDF文件进行密码保护,而不必以明文形式存储用户密码

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

--编辑--


我只是想澄清一下,我想做的是允许用户在系统中输入密码一次,然后在这之后的任何时候都可以使用该密码生成的密钥对PDF文件进行加密。大多数PDF库都要求以明文形式传递密码,我想要的是一个接受“公共”密钥的加密函数。

有包含加密的开源Java和C#PDF库。

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

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

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

大多数将支持旧的基本形式。很少有人支持AES 256位加密。这取决于什么对你来说是重要的


我从事ABCpdf.NET软件组件的工作,因此我的回复可能以ABCpdf为基础。这正是我所知道的。:-)“

我想我已经在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"));
    }
}
if(V<5)
{
//对于V<5,用户密码由所有者加密
//密码,并且用户密码始终用于
//计算加密密钥。
此->加密密钥=计算加密密钥(
此->用户(密码、数据);
}
其他的
{
//对于V>=5,可以单独使用任一密码
//计算加密密钥,两个密码都不能
//用来恢复另一个。
bool perms_有效;
此->加密密钥=使用密码恢复加密密钥(
此->提供了密码、数据、密码(有效);
如果(!perms_有效)
{
警告(QPDFExc(qpdf_e_损坏_pdf,此->文件->getName(),
“加密字典”,此->文件->getLastOffset(),
“加密字典中的/Perms字段”
“与预期值不匹配”);
}
}
无论哪种方式,计算加密密钥都需要密码。我怀疑计算出的加密密钥可能会受到反向工程的影响而恢复密码,因此存储这也是一个坏主意

我能想到的备选方案是:

  • 要求用户在每次下载文件时重新输入密码
  • 为每个用户设置一个不太安全的辅助密码-仅用于加密PDF文件。请确保该密码与用户的主密码不同

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

    什么会让你不得不以明文形式存储用户密码?@mkl我正在使用的命令行工具(qpdf)仅提供纯文本密码选项。在加密过程中的某个步骤中,您的密码在某个地方以纯文本形式存在,即使仅在内存中也是如此。如果这对您合适,任何合适的通用PDF库都可以。对于运行时环境或库的授权详细信息是否有任何限制?@mkl请参阅我的编辑以获得澄清。你确定你没有混淆这两个概念吗?PDF既知道基于密码的(对称)也知道基于证书的(非对称)加密,您使用的单词密码指向前一种模式,而您使用的公钥指向后一种模式。谢谢。我查看了Java源代码。它可能可以根据我的需要进行修改。我甚至不会说几乎每个PDF库都支持它。例如,我惊讶地看到两个主要的PDF库Perl中的库(CAM::PDF和PDF::API2)不支持OP正在尝试做的事情,即加密由另一个程序创建的未加密PDF。如果您查看PDF规范,很明显的原因是什么,添加到库中肯定不简单。