Diffie-Hellman(簡稱DH)是密鑰交換算法之一,它的做用是保證通訊雙方在非安全的信道中安全地交換密鑰。目前DH最重要的應用場景之一,就是在HTTPS的握手階段,客戶端、服務端利用DH算法交換對稱密鑰。javascript
下面會先簡單介紹DH的數理基礎,而後舉例說明如何在nodejs中使用DH相關的API。html
要理解DH算法,須要掌握必定的數論基礎。感興趣的能夠進一步研究推導過程,或者直接記住下面結論,而後進入下一節。java
假設客戶端、服務端挑選兩個素數a、p(都公開),而後node
Ka = Yb^Xa mod p
= (a^Xb mod p)^Xa mod p
= a^(Xb * Xa) mod p
= (a^Xa mod p)^Xb mod p
= Ya^Xb mod p
= Kb算法
能夠看到,儘管客戶端、服務端彼此不知道對方的Xa、Xb,但算出了相等的secret。安全
結合前面小結的介紹來看下面代碼,其中,要點之一就是client、server採用相同的素數a、p。less
var crypto = require('crypto');
var primeLength = 1024; // 素數p的長度
var generator = 5; // 素數a
// 建立客戶端的DH實例
var client = crypto.createDiffieHellman(primeLength, generator);
// 產生公、私鑰對,Ya = a^Xa mod p
var clientKey = client.generateKeys();
// 建立服務端的DH實例,採用跟客戶端相同的素數a、p
var server = crypto.createDiffieHellman(client.getPrime(), client.getGenerator());
// 產生公、私鑰對,Yb = a^Xb mod p
var serverKey = server.generateKeys();
// 計算 Ka = Yb^Xa mod p
var clientSecret = client.computeSecret(server.getPublicKey());
// 計算 Kb = Ya^Xb mod p
var serverSecret = server.computeSecret(client.getPublicKey());
// 因爲素數p是動態生成的,因此每次打印都不同
// 可是 clientSecret === serverSecret
console.log(clientSecret.toString('hex'));
console.log(serverSecret.toString('hex'));複製代碼
迪菲-赫爾曼密鑰交換spa