Gpg
如何強制“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
將文件發送到異地進行備份之前對其進行加密。如果大文件被中斷(無論出於何種原因:網路問題、遠端伺服器崩潰等),我希望能夠恢復大文件的備份。使用確定性加密,這很容易:獲取上傳的字節數(加密內容),再次加密文件,檢查N個字節的雜湊,如果它們匹配,則繼續其餘的。但是,如果加密結果不確定,則無法恢復上傳。
你不能。最普遍接受的安全定義(例如,語義安全和自適應選擇密文安全)不允許確定性加密。
要了解原因,假設我問了您兩個是/否問題,並且您在某個預共享密鑰下確定性地加密了我的答案。使用確定性加密,任何竊聽者都會知道您對這兩個問題的答案是否相同。
當然,還有一些針對小眾案例的不太安全的加密形式(例如,收斂加密)。但是像 gpg 這樣的通用加密工具需要提供更好的安全性,因為它是為一般用途而設計的。
更新如果需要參考,可以查看 GPG 原始碼
agent/protect.c
。你會看到 IV 是從 開始設置的gcry_create_nonce
,你可以在libgcrypt 手冊中找到它:用長度不可預測的字節填充*緩衝區。*這通常稱為隨機數,也可用於初始化向量和填充。這是一個幾乎獨立於其他隨機函式的額外函式,原因有 3 個:它更好地保護了正常隨機生成器的內部狀態,提供更好的性能並且不會耗盡寶貴的熵池。