HTTPS 能防止重放攻擊嗎?為什么?
SSL1.0安全隱患
SSLv1.0是Netscape公司發明的Secure Socket Layer 1.0版本,也是第一個版本,用于安全加密保護http,http主要用于包裝電子購物。
但是由于SSLv1.0發送方不對發出的message個數計數,接收方也不對接收到的message計數。換句話說,通信雙方message數量沒有記憶,這樣就給第三方可乘之機。第三方可以將截獲的message再次發出,這樣接收方校驗成功,于是提交給應用程序。應用程序會再次執行code,如果這個執行code是轉賬付款,那問題就大了。
這個安全漏洞很快就被SSLv2.0修復,修復方法很簡單,發送方對發出的message個數計數,接收方也對接收到的message計數。然后將message的序號,作為HMAC輸入的一個參數,加密發送到對方。
接收方接收到之后,和發送方執行同樣的校驗方法(HMAC),由于雙方的輸入參數是一模一樣的,而且message的序號也是一樣的,所以校驗通過,提交給應用程序。如果被第三方replay,就無法通過安全校驗,從而被丟棄,對應用程序的影響=0。
假設發送方老王發送的message的序號 =3, 且這個message被接收方老李成功接收。
第三方老黑將序號=3的message 重新發一次,那么老李收到message的時候,序號就不是3了,因為序號3已經收到了,至于序號是4、5、6還是什么不重要,重要的是序號≠3,那么安全校驗一定會以失敗而告終。
聰明的讀者可能會說,為何老黑不將message的序號3修改成4、5、6或者別的,那還是有可能成功的,對嗎?
很遺憾,你無法做到,因為message序號是隱含的(implicit)。
什么是隱含序列號?
隱含是什么意思呢?
也許讀者會很意外,message報文本身是沒有序號的,這個序號只有發送方知道。老王你連自己發送了多少個message都不知道嗎?每發一個包裹(message)先后次序都不知道?
老王說,俺當然知道。
老李我問你,你從老王收多少個包裹知道嗎,每個包裹先后次序知道嗎?
老李幽幽地說,俺收到多少個包裹是知道的,先后次序(序號)也是知道的,本來俺無法確定包裹來自老王,但是好在有HMAC安全校驗碼的幫助,包裹確實都來自于老王。因為除了俺之外,只有老王知道HMAC的密鑰。
為何SSL/TLS要跑在TCP上,而不是UDP上?
答案也很簡單,因為UDP無法確保message的到達順序,會造成雙方message的序號不一致而通信失敗。而TCP可以確保message的到達順序,可以確保雙方序號一致,從而確保HMAC校驗成功。