如何强制“gpg2”始终为相同的输入产生相同的输出?

如何强制“gpg2”始终为相同的输入产生相同的输出?

当同一个字符串被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 个:它更好地保护常规随机生成器的内部状态,提供更好的性能并且不会耗尽宝贵的熵池。

相关内容