如何让Rust生成的ECDH共享密钥与NodeJS/C实现一致?
解决Rust secp256k1 ECDH共享密钥与NodeJS/C不匹配的问题
问题核心是不同语言的secp256k1库对ECDH共享密钥的默认输出格式存在差异:
- NodeJS/C的实现默认提取**共享密钥点的x坐标(32字节)**作为最终共享密钥
- Rust的
secp256k1库中,shared_secret_point返回的是未压缩形式的共享点(64字节,前32字节为x坐标,后32字节为y坐标)
要实现完全匹配,直接截取shared_secret_point返回值的前32字节即可。
代码示例
假设你已持有对方公钥和自身私钥,Rust代码实现如下:
use secp256k1::{Secp256k1, SecretKey, PublicKey}; fn main() { let secp = Secp256k1::new(); // 替换为真实私钥 let secret_key = SecretKey::from_slice(&[0x1; 32]).unwrap(); // 替换为真实公钥(未压缩格式,前缀0x04+64字节坐标) let pub_key = PublicKey::from_slice(&[0x04, /* 32字节x坐标 */, /* 32字节y坐标 */]).unwrap(); // 获取64字节的未压缩共享点 let shared_point = secp.shared_secret_point(&secret_key, &pub_key).unwrap(); // 截取前32字节得到与NodeJS/C一致的共享密钥 let shared_key = &shared_point[0..32]; // 此时shared_key为32字节,与NodeJS/C结果完全匹配 }
额外说明
如果你的NodeJS代码对x坐标做了额外哈希(比如SHA-256),需要在Rust中对截取的x坐标执行相同哈希操作。但根据你描述的“前32字节吻合”,说明NodeJS未做额外哈希,直接使用了x坐标,因此仅需截取前32字节即可。
内容的提问来源于stack exchange,提问作者fadedbee
相关产品推荐
相关产品推荐

