Gpg

如何強制“gpg2”始終為相同的輸入產生相同的輸出?

  • June 28, 2020

當同一字元串被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將文件發送到異地進行備份之前對其進行加密。

如果大文件被中斷(無論出於何種原因:網路問題、遠端伺服器崩潰等),我希望能夠恢復大文件的備份。使用確定性加密,這很容易:獲取上傳的字節數(加密內容),再次加密文件,檢查N個字節的雜湊,如果它們匹配,則繼續其餘的。但是,如果加密結果不確定,則無法恢復上傳。

你不能。最普遍接受的安全定義(例如,語義安全和自適應選擇密文安全)不允許確定性加密。

要了解原因,假設我問了您兩個是/否問題,並且您在某個預共享密鑰下確定性地加密了我的答案。使用確定性加密,任何竊聽者都會知道您對這兩個問題的答案是否相同。

當然,還有一些針對小眾案例的不太安全的加密形式(例如,收斂加密)。但是像 gpg 這樣的通用加密工具需要提供更好的安全性,因為它是為一般用途而設計的。

更新如果需要參考,可以查看 GPG 原始碼agent/protect.c。你會看到 IV 是從 開始設置的gcry_create_nonce,你可以在libgcrypt 手冊中找到它:

長度不可預測的字節填充*緩衝區。*這通常稱為隨機數,也可用於初始化向量和填充。這是一個幾乎獨立於其他隨機函式的額外函式,原因有 3 個:它更好地保護了正常隨機生成器的內部狀態,提供更好的性能並且不會耗盡寶貴的熵池。

引用自:https://unix.stackexchange.com/questions/595428