Public-Key

PGP 維護電子郵件安全的方式是否最佳?

  • June 14, 2016

我讀了一本名為“電腦網路:一種自上而下的方法”的書。它討論了 PGP 如何在 Alice 和 Bob 之間創建電子郵件消息以保持機密性、完整性和真實性。讓我在非常高的級別定義一些術語和程序:

m :              email message
H() :            cryptographic hash function
Ka_priv_sign() : signing using Alice's private key
|| :             contacternation
Ks :             session key
Ks_enc():        encryption using session key
Kb_pub_enc():    encryption using bob's public key
blob :           The final data blob Alice sends to Bob.

為了向 Bob 發送電子郵件,Alice 首先使用她的私鑰對消息進行簽名:

m || Ka_priv_sign(H(m))

Alice 然後加密消息和簽名

blob = Kb_pub_enc(Ks) || Ks_enc(m || Ka_priv_sign(H(m))) 

Alice 會將這個最終的 blob 發送給 Bob。

密碼學在這裡似乎有問題,因為數字簽名是在加密之前應用的,而加密不提供數據完整性。我認為正確的操作順序應該是:

Alice 首先用會話密鑰加密消息,然後用 Bob 的公鑰加密會話密鑰:

Kb_pub_enc(Ks) || Ks_enc(m)

Alice 然後在對加密結果進行雜湊處理後對它們進行簽名:

blob' = Kb_pub_enc(Ks) || Ks_enc(m) || Ka_priv_sign(H(Kb_pub_enc(Ks) || Ks_enc(m)))) 

問題:

PGP 是否還在使用今天教科書描述的方式?你覺得我的建築更好嗎?

正如 fgrieu 在他的回答中指出的那樣,使用先簽名後加密可能是處理加密和簽名消息的最佳方式。

然而,當研究RFC 4880中的 OpenPGP 格式時,它似乎同時使用了 PKCS#1 v1.5 填充和 CBC 模式加密。這兩種方案都容易受到填充預言機攻擊。

因此,重要的是要確保軟體不易受到填充預言機攻擊。一種方法是僅在每個消息基礎上對其進行解密,或者將其用於就地加密/簽名。另一種方法是確保 PGP 的實現不易受到填充預言機攻擊。

我不會稱其為“最佳” -應該使用更現代的方案來加密消息和包裝的對稱密鑰。

所以基本上簽名然後加密是可以的,但用於加密的方案不是。

是的,問題中的 PGP 草圖在當今的密碼學教科書中是合理的,從電腦安全的角度來看也是合理的。應用數字簽名然後加密(關鍵:包括簽名)確實為消息提供了數據完整性和機密性。

PGP 的做事方式的特點是能夠破譯消息的人可以將其變成由 Alice 簽名的明文消息,任何人(知道並信任 Alice 的公鑰)都可以驗證該消息。在許多情況下,這是一個功能。

當 PGP 被濫用時,它有時會成為一個弱點。假設 Alice 向 Mallory 發送一條消息,比如“我愛你”,由 Alice 簽名,加密到 Mallory;馬洛里可以解密消息,並將其轉發給鮑勃,仍然由愛麗絲簽名,甚至可能重新加密給鮑勃;如果 Bob 不理解 PGP 簽名的真正含義,他可能會被騙以為 Alice 關心他。這也是愛麗絲的錯:她應該簽署一個更無上下文的資訊,比如“我愛你馬洛里”(並且更有選擇性)。這裡有更多的例子(它採取了有爭議的立場,這是 PGP 中的一個缺陷)。

還有一個論點,由一些電腦安全材料合法地提出,使用 PGP 中的簽名然後加密,接收方解密未經身份驗證的東西,並且可以允許在解密中或之後利用軟體錯誤。在 PGP 的上下文中,該論點不成立:PGP 旨在支持未經身份驗證的加密消息;並且一個人合法地希望能夠讀取一個人無法驗證的消息,因為缺少所謂的簽名者的可信公鑰。


更新:這個答案只是關於問題中描述的 PGP 格式的整體結構的健全性;由於缺乏定義,我沒有觸及“最優性”;也不嘗試檢查詳細的 PGP 格式和實現(它們不是最先進的),如其他答案中所討論的那樣。

引用自:https://crypto.stackexchange.com/questions/37031