当同一个字符串被gpg2
多次加密时,即使加密密钥相同,结果也会不同。
$ echo "secret message" | gpg2 --batch --passphrase-file /tmp/key --output - --symmetric > /tmp/r
$ xxd r
00000000: 8c0d 0409 0302 49c1 3718 910a c1ca f3d2 ......I.7.......
00000010: 4401 85a4 6885 26ef 7d4f c403 984d 6c03 D...h.&.}O...Ml.
00000020: 8c68 9ba9 4ea6 b214 2e9c 474a 0666 be52 .h..N.....GJ.f.R
00000030: 5d79 53cd d24b 387f 56e1 3a22 4401 a407 ]yS..K8.V.:"D...
00000040: 881b c641 8b10 b1e7 6662 aaee 3382 7151 ...A....fb..3.qQ
00000050: 565b 172e 74 V[..t
$ echo "secret message" | gpg2 --batch --passphrase-file /tmp/key --output - --symmetric > /tmp/r
$ xxd r
00000000: 8c0d 0409 0302 dde5 397c 8bfa 4c29 f3d2 ........9|..L)..
00000010: 4401 ca3d bba8 8259 b9e9 7a18 4031 9e86 D..=...Y..z.@1..
00000020: 4861 ddca 8bf3 dbff f4c7 c40e be3f 4092 Ha...........?@.
00000030: 5dec 4dab ef31 3712 1fa3 76e1 4381 ed6f ].M..17...v.C..o
00000040: bb0d ca49 be0d 4256 9049 2468 07da 3ba7 ...I..BV.I$h..;.
00000050: c338 74e8 d4 .8t..
发生这种情况是因为每次gpg2
运行时,它使用两个随机块在流的开头。
如何强制gpg2
为相同的输入始终产生相同的输出?
有些人可能会想,为什么我需要这样的东西。事实上,我在将gpg2
文件发送到异地进行备份之前对它们进行加密。
我希望能够在大文件中断时恢复大文件的备份(无论出于何种原因:网络问题、远程服务器崩溃等)。使用确定性加密,这很容易:获取上传的字节数(加密内容),再次加密文件,检查哈希值氮字节,如果匹配,则继续处理剩余的字节。然而,如果加密结果不确定,则无法恢复上传。
答案1
你不能。最普遍接受的安全定义(例如,语义安全和自适应选择密文安全)不承认确定性加密。
要了解原因,请想象我问您两个是/否问题,并且您在某个预共享密钥下确定性地加密我的答案。通过确定性加密,任何窃听者都会知道您对这两个问题的答案是否相同。
当然,还有一些针对利基用例的不太安全的加密形式(例如,聚合加密)。但是像 gpg 这样的通用加密工具需要提供更好的安全性,因为它是用于通用用途的。
更新如果需要参考,可以查看 中的 GPG 源代码agent/protect.c
。您将看到 IV 已从 中设置gcry_create_nonce
,您可以在中找到记录libgcrypt 手册作为:
充满缓冲和长度不可预测的字节。这通常称为随机数,也可用于初始化向量和填充。这是一个几乎独立于其他随机函数的额外函数,原因有 3 个:它更好地保护常规随机生成器的内部状态,提供更好的性能并且不会耗尽宝贵的熵池。