我們應該先簽名後加密,還是先加密後簽名?
通常,我們希望發送經過 (a) 加密的消息,因此被動攻擊者無法發現消息的明文,以及 (b) 使用私鑰數字簽名進行簽名,因此主動攻擊者無法讓 Alice 認為Bob 沒有收到消息。
(a) 從(散列的)明文生成數字簽名,然後加密包含明文消息和數字簽名的文件是否更好?還是(b)首先加密消息,然後從(散列)加密文件生成數字簽名更好?或者 (c) 以其他方式結合加密和公鑰數字簽名?
一個密切相關的早期問題(我們應該 MAC-then-encrypt 還是 encrypt-then-MAC?)似乎關注對稱密鑰 MAC 身份驗證。正如Robert I. Jr. 之前所問的那樣,(對稱密鑰)MAC-then-encrypt 的相同問題是否適用於(public-key)sign-then-encrypt?
假設您要詢問公鑰簽名+公鑰加密:
**簡短回答:**我建議先簽名後加密,但要先在郵件中添加收件人姓名。
**長答案:**當 Alice 想要向 Bob 發送經過身份驗證的消息時,她應該對消息進行簽名和加密。特別是,她將 Bob 的名字添加到消息中,使用她的私鑰對其進行簽名,將她的簽名附加到消息中,在 Bob 的公鑰下加密整個內容,並將生成的密文發送給 Bob。Bob 可以解密、驗證簽名,並確認這確實來自 Alice(或與她共享私鑰的人)。確保您使用 IND-CCA2 安全公鑰加密方案和 UF-CMA 安全公鑰簽名方案(即,對存在偽造攻擊安全的方案)。
**理由:**這樣做的原因是為了擊敗一些微妙的攻擊。這些攻擊不一定在所有場景中都是問題,但最好盡可能強化方法。完整的解釋將佔用比此處更多的空間,但請參閱下面的推理草圖。
關於是先簽名還是先加密的詳細分析,以下是一個很好的資源:S/MIME、PKCS#7、MOSS、PEM、PGP 和 XML 中的缺陷簽名和加密。
我不推薦加密然後簽名。它可以工作,但在某些情況下它有一些微妙的缺陷,因為簽名並不能證明發送者知道明文的上下文。例如,假設 Alice 的 SSH 客戶端發送消息“親愛的 SSH 伺服器,請將我的公鑰附加到 /root/.ssh/authorized_keys – 你可以知道我是授權的,因為我知道 root 密碼是 lk23jas0”(然後加密用 Alice 的公鑰簽名),如果 root 密碼正確,SSH 伺服器會對其進行操作。然後 Eve 可以竊聽,擷取此消息,剝離 Alice 的簽名,用 Eve 自己的密鑰對密文進行簽名,並將其發送到 SSH 伺服器,即使 Eve 不知道 root 密碼,也可以獲得 root 級別的訪問權限。