摘要:很多安全規范及安全文章中都提到一條規則:先加密后簽名是不安全的,應當先簽名后加密。這條規則背后的原理是什么?先加密后簽名一定不安全嗎?本文為您一一解答。
先簽名后加密是指先對消息進行簽名,然后對消息的簽名值和消息一起進行加密。如果采用先加密后簽名的方式,接收方只能知道該消息是由簽名者發送過來的,但並不能確定簽名者是否是該消息的創建者。比如在發送一個認證憑據時采用先加密后簽名的方式,消息在發送過程中就有可能被第三方截獲並將認證憑據密文的簽名值修改為自己的簽名,然后發送給接收方。第三方就有可能在不需知道認證憑據的情況下通過這種方式來通過認證獲取權限。
采用先簽名后加密方式可以避免這類問題的發生,因為只有在知道消息明文的情況下才能對其進行簽名。
雖然不同的規范描述有差異,但核心觀點都是“先簽名后加密”。但是這條規范的適用場景是什么呢,“先加密后簽名”一定不安全嗎?需要深挖一下。
如果使用“先加密后簽名”,則消息發送方Alice和消息接收方Bob的處理過程如下圖:

Alice發送的明文消息先經過Alice私鑰簽名,再將消息明文和消息簽名一起使用Bob的公鑰加密,密文經過網絡傳輸到Bob。因為Bob使用私鑰解密還原出消息明文和簽名,而私鑰只有Bob持有,這能保證消息明文不會泄露給第三方Eve,然后Bob使用Alice的公鑰驗證消息明文和簽名是否一致,因為Alice的簽名只有Alice的公鑰才能驗證,這能保證消息一定來自Alice,不可抵賴,且沒有被第三方Mallory篡改。在拿不到消息明文的情況下,無法計算出消息簽名,而還原消息明文又必須使用Bob的私鑰,這樣就能防止網絡傳輸過程中的中間人進行篡改攻擊。
假如“先加密后簽名”,會存在什么樣的攻擊風險呢,先看下“先加密后簽名”的處理流程:

消息明文使用Bob的公鑰加密,不可能泄露給第三方,簽名也有了,可以防篡改,不仔細看的話,似乎沒什么問題。繼續看下面這張圖:

如果存在一個中間人Mallory可以攔截Alice和Bob的消息,在不篡改消息明文和密文的情況下,使用Mallory的私鑰對消息密文進行簽名,並替換Alice原始的簽名,最后篡改后的消息傳輸給接收方Bob,Bob仍然可以成功解密明文,同時用Mallory的公鑰成功驗證簽名,最終這條消息會被Bob認為是Mallory發送的合法消息。
“先加密后簽名”一定不安全嗎
從上面的演示來看,“先加密后簽名”似乎一定不安全,是這樣嗎?中間人Mallory針對“先加密后簽名”進行替換簽名攻擊得手的前提條件:
1、 接收方Bob根據簽名內容中的證書ID找到對應的Mallory公鑰來驗證簽名。
2、 接收方Bob僅使用公鑰驗簽來識別發送方的身份。
只要打破上面的任意一個前提,“先加密后簽名”也是安全的:
1、 Bob使用固定的公鑰來驗證簽名,而不是根據簽名內容來找對應公鑰,或者不使用多個公鑰嘗試驗簽。即Mallory替換簽名后,Bob仍然用Alice的公鑰驗證簽名,肯定能發現請求被篡改。
2、 Bob使用公鑰+應用層屬性一起識別發送方的身份,假設Alice在消息明文中攜帶自己的用戶ID,Bob驗證公鑰和用戶ID是否匹配,即使Mallory替換簽名也無法攻擊。
所以“先加密后簽名”是不是安全,還要看業務應用是怎么設計的,不能絕對的認定為不安全。
本文分享自華為雲社區《“先簽名后加密”的思考》,原文作者:卡農。
