如何讓PGP短密鑰ID免于碰撞攻擊?
針對開發人員的碰撞攻擊讓我們發現Pretty Good Privacy(PGP)短ID的漏洞,該漏洞允許攻擊者創建假ID密鑰,這會給收件人解密或驗證郵件制造問題。那么,這個漏洞的工作原理是什么,以及為什么短密鑰ID會成為問題?
Michael Cobb:當為電子郵件、文檔或文件創建哈希值或者消息摘要時,需要通過使用密碼散列函數來生成內容的短數字指紋,這種數學算法會將任意大小的數據映射到短的固定長度值作為其唯一標識。哈希值被廣泛用于安全的很多方面,例如數字簽名和數據完整性檢查,人們通常會精心選擇散列函數以確保它們有較強的抗碰撞性--即兩個不同的輸入無法創建相同的散列值,因為攻擊者的碰撞攻擊會試圖尋找具有相同散列值的兩組不同數據片段。
而PGP是對消息或文件進行加密和數字簽名的加密工具,PGP的用戶會有公鑰和私鑰,公鑰通常在密鑰服務器發布。由于這些密鑰都非常長(通常為1024至8096位),所以我們通常使用公鑰的指紋或哈希值來標記密鑰,讓某些密鑰管理工作更容易和更快速,例如驗證屬于其他用戶的密鑰或者驗證證書頒發機構。然而,當轉換為十六進制數字時指紋為40位,這對于人類來說仍然太長而難以使用,因此人們和很多應用僅使用指紋的最后八位數。這被稱為短密鑰ID--長ID是指指紋的最后16位數字。下面是例子:
指紋: 0D29 F56F 12BD BA07 7B37 15AB 851F 799A B4FF 1057
長ID: 851F 799A B4FF 1057
短ID: B4FF 1057
雖然現代密鑰散列函數幾乎不存在具有相同哈希值的兩個輸入,但兩個哈希值最后八位數相同的幾率還是很高。事實上,我們已經發現很多具有相同短密鑰ID的欺騙性PGP密鑰。
多年來,大家已經知道這種碰撞攻擊成功的可能性。在2011年,軟件工程師Asheesh Laroia有效證明了這種攻擊的可行性,這個問題在“RFC 4880:OpenPGP Message Format”3.3章節中也有提及--“不應該假定密鑰ID為唯一標識”。盡管如此,使用短密鑰ID仍然是常見做法,并構成真正威脅,特別是當涉及文件下載的完整性時,例如Linux內核。
盡管PGP本身沒有缺陷或漏洞,但使用短密鑰ID基本上是不安全的糟糕做法。用戶不應該信任比公共PGP密鑰完整指紋更短的ID用于驗證;密鑰ID的目的是幫助搜索密鑰,而不是驗證它。用戶和軟件都需要開始顯示和檢查完整指紋,或者至少使用長ID。長密鑰ID也可能存在碰撞,但可能性較小。軟件開發人員應該明確編寫或重新編寫代碼以包含整個指紋,畢竟云計算使得攻擊者可為長密鑰ID生成碰撞攻擊。現在那些將PGP密鑰短ID印在名片背面的PGP支持者們可能會想要增加指紋的前兩位來幫助他人驗證其密鑰。