1. 程式人生 > >DH演算法及原始碼解讀

DH演算法及原始碼解讀

【主流的金鑰交換方式】

敏感資料資訊保安傳輸需要對敏感資訊加密,加密的金鑰涉及到傳輸兩端的金鑰協商和交換,目前主要兩種金鑰交換的機制有:

1. 基於非對稱金鑰的實現:請求方用接收方的公鑰加密自己的金鑰,接收方用自己的私鑰解密得到請求方的金鑰,反之一樣,從而實現金鑰的交換

2. DH金鑰交換演算法

【DH金鑰交換演算法】

雙方協商用同一個大素數p和素數的原根g,各自生成隨機數XA,XB。請求方將g的xA次方mod p產生數值傳送給接收方,接收方再將g的XB次方mod p產生的數值傳送給請求方,請求方再對接收的數值做XA次方並對p求餘運算,接收方對接收的數值做XB次方並對p求餘運算,最終形成共同的金鑰K,以達到金鑰的交換。

假如使用者A和使用者B希望交換一個金鑰;

  1. 取素數p和整數ggp的一個原根,公開gp
  2. A選擇隨機數XA<p,並計算YA=g^XA mod p
  3. B選擇隨機數XB<p,並計算YB=g^XB mod p

每一方都將X保密而將Y公開讓另一方得到

A計算金鑰的方式是:K=(YB) ^XA modp

B計算金鑰的方式是:K=(YA) ^XB modp

A和B的K是相同的,K是共享祕鑰

【DH演算法原始碼解讀】

主要涉及jdk中jce.jar、sunjce_provider.jar、rt.jar三個安全jar包。

主要涉及的幾個類keyPairGenerator

DHPrivateKeySpec, DHPublicKeySpec, DHPublicKey DHPrivateKey DHKeyFactory, DHKeyAgreement幾個類。

接下來主要針對keyPairGeneratorDHKeyFactoryDHKeyAgreement這幾個類的原始碼進行闡述:

keyPairGenerator形成公私鑰的key生成器:生成DHPublicKeyDHPrivateKey

DHKeyFactory:公私鑰物件轉換器工廠類:裡面提供engineGeneratePublic(KeySpec paramKeySpec)protected PrivateKey engineGeneratePrivate(KeySpec paramKeySpec)

用來轉換資料,如下是engineGeneratePrivate的原始碼:

從原始碼中看出會根據paramKeySpec不同用不同的方法生成的DHPrivateKey,為了考慮語言相容性,統一採用PKCS8EncodedKeySpec

接下來談下協商的核心類:DHKeyAgreement

首先engineInit(Key paramKey, SecureRandom paramSecureRandom)提供初始化資料,包括P,G,privateKey,下面是對應的原始碼,b對應Pc->G,d對應privateKey

Key engineDoPhase(Key paramKey, boolean paramBoolean)初始化publickey資料,如下是部分原始碼:其中e對應到的就是publicKey.

最後這個方法也就是核心方法,協商的演算法byte[] engineGenerateSecret(),返回的是協商後的金鑰位元組陣列,原始碼如下:接下來具體分下下面程式碼。

從上面原始碼中看到最核心的程式碼就一句:BigInteger localBigInteger2 = this.e.modPow(this.d, localBigInteger1);把它轉成數學方式的表示式為: publicKey^privateKey mod p = sharekey

再結合DH演算法原理對上面就可以更好理解了:

DH演算法:雙方協商用同一個大素數p和 素數p的原根g,各自生成隨機數X,Y。請求方將g的X次方mod p產生的數值傳送給接收方,接收方將g的Y次方mod p產生的數值傳送給請求方。請求方再對接收的數值做X次方運算,接收方對接收的數值做Y次方運算,最終生成一樣的共享金鑰,完成金鑰的交換。