参考给定Java代码实现X25519 DH密钥协商的Node.js版本
问题原因
你原有Node.js代码的错误点如下:
- X25519是固定参数的椭圆曲线密钥协商算法,不需要指定modulusLength,也不能用通用的
crypto.createDiffieHellman(该方法用于普通DH算法,不支持X25519) - 导入对方公钥时没有正确解析Java输出的SPKI格式Base64编码公钥
- 密钥导出逻辑和Java实现不匹配
可正常运行的Node.js实现代码
const crypto = require('crypto'); const ecdhKeyagreement = () => { let m_privateKey; // 公钥是SPKI格式的Base64编码,和Java输出的publicKey格式完全对齐 let m_publicKeyBase64; let m_sharedKeyBase64; const generatePublicAndPrivateKeys = () => { const {publicKey, privateKey} = crypto.generateKeyPairSync('x25519', { publicKeyEncoding: { type: 'spki', format: 'der' }, privateKeyEncoding: { type: 'pkcs8', format: 'der' } }); // 存储私钥为KeyObject方便后续计算 m_privateKey = crypto.createPrivateKey({ key: privateKey, format: 'der', type: 'pkcs8' }); // 公钥转Base64输出,和Java的myKP.getPublic().getEncoded()格式完全一致 m_publicKeyBase64 = publicKey.toString('base64'); }; const computeSharedKey = (peerPubBase64) => { // 解析Java端输出的SPKI格式公钥 const peerPubBuffer = Buffer.from(peerPubBase64, 'base64'); const peerPublicKey = crypto.createPublicKey({ key: peerPubBuffer, format: 'der', type: 'spki' }); // 计算共享密钥,X25519生成的共享密钥固定32字节,和Java结果一致 const sharedKeyBuffer = crypto.diffieHellman({ privateKey: m_privateKey, publicKey: peerPublicKey }); m_sharedKeyBase64 = sharedKeyBuffer.toString('base64'); return m_sharedKeyBase64; }; return { generatePublicAndPrivateKeys, computeSharedKey, getPublicKey: () => m_publicKeyBase64, getSharedKey: () => m_sharedKeyBase64 }; }; // 测试用例 const my_obj = ecdhKeyagreement(); my_obj.generatePublicAndPrivateKeys(); // 输出本地公钥,可直接传给Java后端使用 console.log('本地公钥(Base64):', my_obj.getPublicKey()); const peerPub = "MCowBQYDK2VuAyEAfMePklV88QMhq8qlVxLI6RK1pV4cFUrMwJgPmrXLyVU="; const sharedKey = my_obj.computeSharedKey(peerPub); // 输出共享密钥,和同参数下Java实现的输出完全一致 console.log('共享密钥(Base64):', sharedKey);
互通说明
- 公钥编码统一使用SPKI DER格式转Base64,和Java中
X509EncodedKeySpec、getPublic().getEncoded()逻辑完全匹配 - 共享密钥计算直接使用Node.js crypto模块的X25519专用diffieHellman方法,输出的32字节共享密钥和Java
KeyAgreement.generateSecret()结果完全一致 - 不需要额外处理密钥填充、格式转换,可直接和原有Java代码互通
内容的提问来源于stack exchange,提问作者PaulYu
相关产品推荐
相关产品推荐

