挑戰的公開簽名作為身份驗證
假設您信任客戶端的公共簽名密鑰,一個簡單的身份驗證協議將發送一個長隨機字元串質詢,並讓客戶端對其進行簽名
由於大多數身份驗證仍然依賴於更複雜的協議,例如通過管道發送某種形式的秘密並在伺服器中對其進行驗證,因此上述協議中肯定存在一些我忽略的弱點。
這種方法有什麼問題?如果您依靠 HTTPS 發送質詢,則大多數 MitM 攻擊面都會被移除,對嗎?
一個簡單的身份驗證協議是發送一個長的隨機字元串質詢,並讓客戶端對其進行簽名
嗯,是。這是進行身份驗證挑戰的最常見方法。但是,您描述的協議有一個重大缺陷:它只能保證客戶端已經看到並接受了隨機挑戰。這保證了客戶端在發出質詢後的某個時間點仍然活著並做出響應:使用隨機質詢實際上可以保證質詢是唯一的,因此該協議不易受到重放攻擊。但這並不能保證挑戰者實際上是在與客戶交談。中間人本可以傳達挑戰及其回應。
如果您依靠 HTTPS 發送質詢,則大多數 MitM 攻擊面都會被移除,對嗎?
也許。如果被挑戰的一方已經被認證,那麼是的。但是,如果被挑戰方已經通過身份驗證,為什麼還要再次對其進行身份驗證?有一種情況是有意義的,即如果您希望被挑戰的一方證明它有第二個身份。例如,您已經連接到一台機器並對其進行了身份驗證,現在您想要驗證該機器的特定使用者。但除此之外,它是多餘的。
現在假設您有一個 TLS 連接,其中只有伺服器經過身份驗證,伺服器發送一個隨機 nonce,客戶端對其進行簽名。這僅驗證合法客戶端願意簽署隨機數。在與另一台伺服器通信時,它可能也願意簽署相同的隨機數。因此,您通常不能依靠它來驗證客戶端。僅當您確定客戶端將僅使用其密鑰向一台特定伺服器進行身份驗證時,這才有效。
我忽略了上述協議中的一些弱點。
正如我上面解釋的那樣,弱點是簽署一個隨機挑戰只驗證挑戰者是否願意簽署這個字元串,這不是很有用。一般來說,如果您想要對某些財產進行保證,簽名必須包含您想要保證的所有資訊(除了隱含在簽名中的簽名方的身份)。隨機挑戰對於避免重放攻擊是必要的,但這還不夠。例如,如果您依靠簽名來建立安全通道,則進入通道設置的所有參數都必須編碼在已簽名的消息中:配置參數、隨機數、臨時密鑰等。這被稱為綁定這些參數的簽名. 特別是,如果通道設置使用某種形式的密鑰交換(通常是 Diffie-Hellman)來設置會話密鑰,則公鑰將包含在要簽名的消息中。這保證了簽名是專門為這個會話製作的,並且不會被中間人重放(這將有一個為合法客戶端的公鑰和中間人的公鑰製作的簽名,而不是合法客戶端的公鑰和合法伺服器的公鑰)。
當建立一個安全通道時,認證簽名通常是在一個副本上完成的,即到目前為止發送的所有消息的明確編碼。在 TLS 中,簽名在 CertificateVerify 消息(TLS 1.2、TLS 1.3)中發送。
由於大多數身份驗證仍然依賴於更複雜的協議,例如通過管道發送某種形式的秘密並在伺服器中驗證它,
不,這不是“大多數”身份驗證的工作方式。TLS 中的伺服器和客戶端身份驗證不是這樣工作的。使用 OAuth 等協議的使用者身份驗證不能這樣工作。經典的密碼認證認證是這樣工作的,但是PAKE(密碼認證的密鑰交換)協議不是這樣工作的(雙方協商共享秘密,只有當客戶端使用正確的密碼時才會共享,而不需要客戶端透露密碼到伺服器)。基於 HTTP cookie 的身份驗證可以像這樣工作。