js实现dh
JavaScript 实现 Diffie-Hellman 密钥交换
Diffie-Hellman (DH) 密钥交换是一种允许双方在不安全的通信信道上建立共享密钥的加密协议。以下是使用 JavaScript 实现 DH 密钥交换的步骤:
使用 Node.js 内置 crypto 模块
Node.js 的 crypto 模块提供了直接支持 DH 密钥交换的 API:
const crypto = require('crypto');
// 创建 DH 实例(使用预定义的 modp14 组)
const alice = crypto.createDiffieHellman('modp14');
const alicePublicKey = alice.generateKeys();
const bob = crypto.createDiffieHellman(alice.getPrime(), alice.getGenerator());
const bobPublicKey = bob.generateKeys();
// 计算共享密钥
const aliceSharedKey = alice.computeSecret(bobPublicKey);
const bobSharedKey = bob.computeSecret(alicePublicKey);
console.log(aliceSharedKey.toString('hex') === bobSharedKey.toString('hex')); // true
浏览器环境实现(WebCrypto API)
现代浏览器支持 WebCrypto API 实现 DH 密钥交换:
async function generateDHKeys() {
// 生成 DH 参数
const params = await crypto.subtle.generateKey(
{
name: "DH",
prime: new Uint8Array([...]), // 大质数
generator: new Uint8Array([2]), // 通常使用 2
namedCurve: "P-256" // 或指定其他曲线
},
true,
["deriveKey"]
);
// 导出公钥
const publicKey = await crypto.subtle.exportKey("jwk", params.publicKey);
// 密钥派生
const sharedKey = await crypto.subtle.deriveKey(
{
name: "DH",
public: peerPublicKey
},
params.privateKey,
{ name: "AES-GCM", length: 256 },
true,
["encrypt", "decrypt"]
);
}
注意事项
- 质数选择:应使用足够大的安全质数(至少 2048 位),预定义组如
modp14是常见选择 - 密钥派生:共享密钥通常需要经过 KDF(密钥派生函数)处理后才用于加密
- 浏览器限制:WebCrypto 的 DH 实现可能因浏览器而异,需检查兼容性
完整示例(Node.js)
const crypto = require('crypto');
function generateDHKeys() {
const dh = crypto.createDiffieHellman(2048);
const publicKey = dh.generateKeys();
return {
privateKey: dh,
publicKey: publicKey
};
}
const alice = generateDHKeys();
const bob = generateDHKeys();
const aliceShared = alice.privateKey.computeSecret(bob.publicKey);
const bobShared = bob.privateKey.computeSecret(alice.publicKey);
console.log(aliceShared.equals(bobShared)); // 验证密钥是否相同
以上实现展示了如何在 JavaScript 环境中完成 DH 密钥交换的核心流程,实际应用中还需结合具体的加密需求完善密钥派生和错误处理机制。







