由 Whitfield Diffie 與 Martin Hellman 兩人名字所組成。
它可以讓雙方在有限的資訊之條件下建立起一個共同金鑰,這個金鑰可以在後續的通訊中作為對稱金鑰來加密通訊內容。
下圖展示其運作過程:
假設Alice和Bob約定共同之顏色為黃色,之後Alice和Bob各自選擇一個祕密顏色,然後把秘密顏色跟一開始的黃色做混合,然後互相傳給對方。
之後把收到對方的顏色和自己的私密顏色混合,則Alice 和 Bob 因為最後產生出的顏色之原料都是黃色 + 橘色 + 藍綠色 之三種顏色所混合成,所以兩人最後得到之顏色會相同。即表示兩人得到了共同的Secret。
小明與阿東 兩人協議好要使用 g = 5 以及 p = 23
小明選擇一個秘密整數 a = 6, 計算A = (g ** a) % p 然後傳給給阿東。
A = (5 ** 6) % 23 = 8.
阿東選擇一個秘密整數b = 15, 計算B = (g ** b) % p 然後傳給小明。
B = (5 ** 15) % 23 = 19.
小明計算 K = (B ** a) % p
(19 ** 6) % 23 = 2.
阿東計算 K = (A ** b) % p
(8 ** 15) % 23 = 2.
最後兩人得到相同之結果K,當作共享的密鑰。
const crypto = require('crypto');
// 產生 Alice 的鑰匙
const alice = crypto.createDiffieHellman(1024);
const aliceKey = alice.generateKeys();
// 產生 Bob 的鑰匙
const bob = crypto.createDiffieHellman(alice.getPrime(), alice.getGenerator());
const bobKey = bob.generateKeys();
// 計算兩人公同的密鑰
const aliceSecret = alice.computeSecret(bobKey);
const bobSecret = bob.computeSecret(aliceKey);
// 驗證兩人之共享金鑰是否相同
console.log(aliceSecret.toString('hex') === bobSecret.toString('hex'));
// 可參考:https://nodejs.org/api/crypto.html#crypto_class_diffiehellman
1.產生 DH 參數檔案
openssl genpkey -genparam -algorithm DH -out dhp.pem
從參數檔案產生私鑰A
openssl genpkey -paramfile dhp.pem -out private_keyA.pem
產生私鑰B
openssl genpkey -paramfile dhp.pem -out private_keyB.pem
產生A 的公鑰
openssl pkey -in private_keyA.pem -pubout -out dhpubA.pem
產生B 的公鑰
openssl pkey -in private_keyB.pem -pubout -out dhpubB.pem
產生共同Secret
A之Secret
openssl pkeyutl -derive -inkey private_keyA.pem -peerkey dhpubB.pem -out secretA.bin
B之Secret
openssl pkeyutl -derive -inkey private_keyB.pem -peerkey dhpubA.pem -out secretB.bin
最後,比較兩個產生出的Secret是否相同
cmp secretA.bin secretB.bin
cpm指令如果兩檔案相同就不會有輸出。