PDF 加密原理
英文:https://qpdf.readthedocs.io/en/stable/encryption.html
PDF 加密
本章从一般角度讨论了 PDF 加密在qpdf中的工作原理。本章并非旨在取代 PDF 规范。请查阅规范以了解完整详情。
PDF 加密概念
- 加密
-
加密是用加密文本(也称为密文)替换明文。如果知道加密密钥,则可以从密文中恢复明文。
PDF 文件由对象结构组成。PDF 对象可能具有多种类型,包括(但不限于)数字、布尔值、名称、数组、字典、字符串和流。在 PDF 文件中,只有字符串和流是加密的。
- 安全处理人员
-
自 PDF 诞生以来,文件加密方式已多次修改。加密由安全处理程序处理。标准安全处理程序基于密码。这是 qpdf 实现的唯一安全处理程序,本文将重点介绍标准安全处理程序。有各种标志可控制使用标准安全处理程序进行加密的具体细节。这些将在下面讨论。
- 加密密钥
-
这是指加密和解密算法使用的实际密钥。它与密码不同。主加密密钥是随机生成的,并以加密形式存储在 PDF 文件中。用于保护 PDF 文件的密码(如果有)用于保护加密密钥。这种设计使得可以使用不同的密码(例如,用户和所有者密码)来检索加密密钥,甚至可以在不更改加密密钥的情况下更改文件的密码。qpdf 可以在使用该选项运行时公开加密密钥,
--show-encryption-key
并且可以在使用该选项运行时接受十六进制编码的加密密钥代替密码--password-is-hex-key
。 - 密码保护
-
密码保护不同于加密。这一点常常被误解。PDF 文件可以加密而不受密码保护。PDF 加密的目的是应该有两个密码:用户密码和所有者密码。任何一个密码都可以用来检索加密密钥。如果使用用户密码打开文件,则符合要求的阅读器应该遵守安全限制,但如果使用所有者密码打开文件,则不必遵守。qpdf不会区分使用哪个密码打开文件。符合要求的阅读器对用户密码和所有者密码的区分使得创建没有密码保护的加密文件变得很常见。这是通过使用空字符串作为用户密码并使用某个秘密字符串作为所有者密码来实现的。当用户打开 PDF 文件时,空字符串用于检索加密密钥,从而使文件可用,但符合要求的阅读器会限制用户的某些操作。
这一切意味着什么?以下是一些需要注意的事情。
-
由于用户密码和所有者密码都用于恢复单个加密密钥,因此从根本上来说,没有办法 阻止应用程序忽略文件的安全限制。任何可以读取加密文件的软件都拥有加密密钥。因此,对 PDF 文件的限制的安全性完全由软件强制执行。任何开源 PDF 阅读器都可以轻松修改以忽略文件的安全限制。PDF 规范对这一点很明确。这意味着 PDF 对不受密码保护的文件的限制只会限制那些不知道如何规避这些限制的用户。
-
如果文件受密码保护,您必须知道至少一个用户或所有者密码才能检索加密密钥。但是,在 40 位加密的情况下,实际加密密钥只有 5 个字节长,很容易被暴力破解。因此,无论密码有多强,使用 40 位加密加密的文件都不安全。对于 128 位加密,默认安全处理程序使用 RC4 加密,这也被认为是不安全的。因此,使用标准安全处理程序安全加密 PDF 文件的唯一方法(截至 2022 年本章的最后一次审查)是使用 AES 加密。这是 256 位加密唯一支持的算法,也可以选择将其用于 128 位加密。但是,没有理由将 128 位加密与 AES 一起使用。如果您要使用 AES,请改用 256 位加密。使用强密码的 256 位 AES 加密 PDF 文件的安全性与使用gpg或 openssl等通用加密工具使用相同密码加密 PDF 文件的安全性相当,但使用 PDF 加密的优势在于除了常规 PDF 查看器之外不需要任何软件。
PDF 加密详细信息
本节介绍 PDF 加密的一些细节。它并未介绍所有细节。如需了解所有细节,请阅读 PDF 规范。但是,此处介绍的细节应该有助于普通用户/开发人员了解加密 PDF 文件的情况。
这里还有更多概念需要理解。
- 算法参数
V
和R
-
有两个参数控制使用标准安全处理程序的加密细节:
V
和R
。V
是指定用于加密文件、处理密钥等的算法的代码。它可以是以下任意值:五
意义
1
原始算法使用 40 位密钥加密文件。
2
原始算法的扩展,允许使用更长的密钥。在 PDF 1.4 中引入。
3
一种未公开的算法,允许文件加密密钥长度在 40 到 128 位之间。在 PDF 1.4 中引入。据信 qpdf 能够读取
V
= 3 的文件,但不能写入此类文件。4
算法的扩展,允许通过处理字符串和流的附加规则对其进行参数化。在 PDF 1.5 中引入。
5
一种算法,允许为字符串和流以及嵌入文件指定单独的安全处理程序,并支持 256 位密钥。在 PDF 1.7 扩展级别 3 中引入,后来在扩展级别 8 中扩展。这是 PDF 2.0 规范 ISO-32000 中的加密系统。
R
是指定标准处理程序修订版的代码。它与 的值紧密相关V
。R
可能具有以下任何值:R
预期 V
2
V
必须为 13
V
必须是 2 或 34
V
必须为 45
V
必须为 5;此扩展从未完全指定并且在某些版本的 Acrobat 中存在了很短的时间。qpdf 能够读取和写入这种格式,但除了测试与格式的兼容性之外,不应将其用于任何其他目的。6
V
必须是 5。这是 PDF 2.0 规范 ISO-32000 中唯一未被弃用的值。 - 加密字典
-
加密的 PDF 文件有一个加密字典。它有几个字段,但对于我们的目的来说,这些是最重要的:
-
V
并R
如上所述 -
O
、U
、OE
、UE
:从用户和所有者密码恢复加密密钥的算法所使用的值。这些值的定义及其使用方式取决于 的值R
。 -
P
:描述存在哪些限制的位字段。这将在下文的PDF 安全限制中讨论
-
- 加密算法
-
PDF 文件可以使用过时的、不安全的 RC4 算法或更安全的 AES 算法进行加密。另请参阅弱加密以了解相关讨论。40 位加密始终使用 RC4。128 位加密可以使用 RC4(出于兼容性原因的默认设置)或从 PDF 1.6 开始使用 AES。256 位加密始终使用 AES。
PDF 安全限制
PDF 安全限制由位字段描述,其值存储在加密字典中的字段中。算法使用的P
值 根据密码恢复加密密钥,这使得值具有防篡改功能。P
P
P
是一个 32 位整数,被视为有符号的二进制补码数。任何位上的 1 都表示已授予权限。PDF 规范将位从 1(最低有效位)编号到 32(最高有效位),而不是更常见的 0 到 31。为了与规范保持一致,本节的其余部分使用基于 1 的编号。
仅使用位 3、4、5、6、9、10、11 和 12。所有其他位均设置为 1。由于位 32 始终设置为 1,因此的值P
始终为负数。(qpdf代表有缺陷的编写器识别正数,将其视为P
无符号数。此类文件已在野外出现。)
以下是位位置的含义。除位 1 和位 2 外,所有未列出的位都必须具有值 1,这两个位必须具有值 0。但是,表中以外的位的值将被忽略,因此在大多数情况下,具有错误的值可能不会破坏任何内容。值为 1 表示已授予权限。
少量 |
意义 |
---|---|
3 |
对于 |
4 |
修改文档,但第 6、9 和 11 位控制的除外 |
5 |
为视障用户无障碍以外的目的提取文本和图形 |
6 |
添加或修改注释,填写交互式表单字段;如果还设置了位 4,则创建或修改交互式表单字段 |
9 |
对于 |
10 |
未使用;以前授予提取可访问性材料的权限,但现在规范不允许限制可访问性,符合规范的读者应将此位视为已设置,无论其值如何 |
11 |
对于 |
12 |
对于 |
qpdf 如何处理安全限制
本节详细描述了 qpdf 库根据P
不同安全选项的各种设置所执行的操作。
-
开始时,除位 1 和位 2 外,所有位均已设置,位 1 和位 2 已清除
-
清除位及说明如下表:
R
争论
已清除的位
R = 2
--print=n
3
R = 2
--modify=n
4
R = 2
--extract=n
5
R = 2
--annotate=n
6
R = 3
--accessibility=n
10
R≥4
--accessibility=n
被忽略
R≥3
--extract=n
5
R≥3
--print=none
3、12
R≥3
--print=low
12
R≥3
--modify=none
4、6、9、11
R≥3
--modify=assembly
4、6、9
R≥3
--modify=form
4、6
R≥3
--modify=annotate
4
R≥3
--assemble=n
11
R≥3
--annotate=n
6
R≥3
--form=n
9
R≥3
--modify-other=n
4
qpdf的选项(无论是在 CLI 级别还是在库级别)允许比大多数工具(包括 Adobe Acrobat)更精细地清除权限位。因此,PDF 查看器可能会根据传递给 qpdf 的选项以令人惊讶的方式做出响应。如果您观察到这种情况,则可能不是因为 qpdf 中的错误。
用户密码和所有者密码
当您使用 qpdf 显示加密参数并使用所有者密码打开文件时,qpdf 有时会显示用户密码,有时则不会。原因如下。
对于V
< 5,用户密码实际上存储在使用从所有者密码派生的密钥加密的 PDF 文件中,主加密密钥使用从用户密码派生的密钥加密。当您打开 PDF 文件时,阅读器首先尝试将给定的密码视为用户密码,并使用它来恢复加密密钥。如果这样做有效,您将受到限制(假设阅读器选择强制执行这些限制)。如果它不起作用,则阅读器将密码视为所有者密码,使用它来恢复用户密码,然后使用用户密码检索加密密钥。这就是为什么使用相同的用户密码和所有者密码创建文件(V
< 5)会导致某些阅读器永远不会允许您以所有者身份打开该文件的原因。当在创建文件时给出空的所有者密码时,用户密码将同时用作用户和所有者密码。通常,当阅读器遇到V
< 5 的文件时,它将首先尝试将空字符串视为用户密码。如果这样做有效,则文件已加密但不受密码保护。如果不起作用,则会提示输入密码。
对于V
≥ 5,主加密密钥是使用用户密码和所有者密码独立加密的。无法从所有者密码中恢复用户密码。是否施加限制取决于使用了哪个密码。在这种情况下,提供的密码(如果有)将同时作为用户密码和所有者密码尝试,并使用有效的密码。通常首先尝试将密码作为所有者密码。(这是 PDF 规范要求做的。)因此,指定用户密码并将所有者密码留空会导致文件以所有者身份打开而没有密码,从而实际上使安全限制变得毫无用处。这就是为什么qpdf要求您在使用 256 位加密时传递 --allow-insecure
以创建具有空所有者密码的文件的原因。