移動端網絡安全-密鑰交換的前世今生(1)

前言:在那個https還沒有普及的黑暗年代,混沌的大地充斥着各種危險的明文傳輸(抱歉,中二了)。相信很多軟件開發人員都遇到過通信加密的問題,早期的一些做法,只是簡單的將對稱加密的密鑰寫死在客戶端中,通過對稱加密的方式進行數據傳輸加密。然而這樣的方案問題也十分明顯,一旦客戶端被反編譯,密鑰泄露,那麼幾乎所有客戶端都暴露在了風險中。

既然不適合將對稱加密的密鑰寫死在客戶端,那是否可以動態生成密鑰並交換呢?

答案當然是肯定的,今天我們來介紹一種密鑰交換協議:

  • DH密鑰交換協議

DH密鑰交換是1976年由Diffie(迪菲)和Hellman(赫爾曼)共同發明的一種算法。使用這種算法,通信雙方僅通過交換一些可以公開的信息就能夠生成出共享的密碼數字,而這一密碼數字就可以被用作對稱密碼的密鑰。

這套算法的核心,就是一個數學公式:

(G^A mod P)^B mod P = G^(AB) mod P;

先來梳理幾個數學概念:

  1. 原根:如果a是素數p的一個原根,那麼數值: mod pa^2 mod p,…,a^(p-1) mod p 是各不相同的整數,且以某種排列方式組成了從1p-1的所有整數。
  2. 離散對數:如果對於一個整數 和素數 的一個原根 a,可以找到一個唯一的指數 i,使得: = (a^i) mod p,其中0p-1,那麼指數 稱爲 的以 爲基數的模p的離散對數。

假設Tom和Jerry想要交換一個密鑰,取素數 P 和整數 G是 P 的一個原根,公開 和 P。

Tom選擇隨機數A (A<P),A即爲Tom的私鑰(打死別泄露),並計算X = G^A mod P。

Jerry選擇隨機數B (B<P),B即爲Jerry的私鑰(同樣嚴格保密),並計算Y = G^B mod P。

Tom將計算結果 X 傳給Jerry,Jerry對 X 再進行計算:

Pass = X^B mod P == (G^A mod P)^B mod P == G^(AB) mod P;

同樣,Tom在拿到Jerry的計算結果Y,也做同樣的計算:

Pass = Y^A mod P == (G^B mod P)^A mod P == G^(BA) mod P;

到這裏,各位看官應該就能明白了,雙方在交換各自的計算結果後,再次計算的結果是一致的,而這個結果Pass,就是最後協商出的密鑰。

網上轉一張圖來梳理下整個流程:

  • 安全性

對於符合特定條件的 P 和 G ,計算 G^A mod P很容易,只是一個簡單的數學運算。但是,想要通過 P 、G、G^A mod P,反向推算 A 卻很困難,這就好比小時候我們去拆家裏的鬧鐘,拆成零件很容易,但是想再把它裝起來....

只要Tom和Jerry使用足夠大的A, B 以及P,那麼暴力破解會變得非常困難,假設 P 是一個至少 300 位的質數,並且 A 和 B 至少有100位長, 那麼即使使用全人類所有的計算資源和當今最好的算法也不可能從A、和 G^(A*B) mod P 中計算出 A*B。

實際上,不管是RSA、離散對數加密還是橢圓曲線加密,公鑰加密算法都是依賴於某個正向計算很簡單(比如多項式時間複雜度),而逆向計算很難(比如指數時間複雜度)的數學難題。對於RSA,這個問題是大整數因子分解問題;對於離散對數加密,是離散對數問題;對於橢圓曲線加密,則爲橢圓曲線上的離散對數問題。

但是這並不意味着這個算法的絕對安全,實際上,DH算法只能保證密鑰本身的安全,卻無法驗證雙方的身份,對於中間人攻擊這樣的手段,是完全無能爲力的(這部分內容,大家有興趣的話之後會再開一篇來詳細講一下)。

 

下一篇,給大家講講另一種更加安全的密鑰交換方式,DH加密算法的進化版:橢圓曲線加密ECDH。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章