所以,
我不知道你的代码为什么不工作,但它可能在某个地方出错。
我在应用加密领域工作,我写了下面的例子来帮助你。
tweetnacl 很好,但在生产系统中你应该使用libsodium 之类的东西。
我写的这段代码展示了如何在 libsodium 的 JS 绑定中执行 elliptic curve Diffie-Hellman 和 EdDSA signature。 它还会打印 bobs pub 和私钥。
要获得这个库,你需要做:
npm install sodium-native 先...
function toHexString(byteArray) {
return Array.from(byteArray, function(byte) {
return ('0' + (byte & 0xFF).toString(16)).slice(-2);
}).join('')
}
//ECDH using curve25519
//totally fresh empty arrays
var alicePub = new Uint8Array(32);
var alicePriv = new Uint8Array(32);
var bobPub = new Uint8Array(32);
var bobPriv = new Uint8Array(32);
//fresh array to hold generated keys
var rxKey = new Uint8Array(sodium.crypto_kx_SESSIONKEYBYTES);
var txKey = new Uint8Array(sodium.crypto_kx_SESSIONKEYBYTES);
var otherRxKey = new Uint8Array(sodium.crypto_kx_SESSIONKEYBYTES);
var otherTxKey = new Uint8Array(sodium.crypto_kx_SESSIONKEYBYTES);
//generate key pairs for Alice and bob
sodium.crypto_kx_keypair(alicePub, alicePriv);
sodium.crypto_kx_keypair(bobPub, bobPriv);
//generate shared keys using ECDH
sodium.crypto_kx_client_session_keys(rxKey, txKey, alicePub, alicePriv, bobPub)
sodium.crypto_kx_server_session_keys(otherRxKey,otherTxKey, bobPub, bobPriv, alicePub)
console.log("ECDH Key Exchange, rx, tx")
console.log(rxKey, txKey)
console.log(otherRxKey, otherTxKey)
console.log(bobPub, bobPriv)
//signature using Ed25519
var publicKey = new Uint8Array(sodium.crypto_sign_PUBLICKEYBYTES);
var privateKey = new Uint8Array(sodium.crypto_sign_SECRETKEYBYTES);
sodium.crypto_sign_keypair(publicKey, privateKey);
var message = new Uint8Array([0,0,1,2,128]);
var similarMessage = new Uint8Array([0,1,1,2,128]);
//sign and message
var signedMessage = new Uint8Array(sodium.crypto_sign_BYTES + message.length)
sodium.crypto_sign(signedMessage, message, privateKey);
console.log("signedMessage: %s", signedMessage);
//verify it works
var bool = sodium.crypto_sign_verify_detached(signedMessage, message, publicKey)
var bool2 = sodium.crypto_sign_verify_detached(signedMessage, similarMessage, publicKey)
console.log("Real message:%s",message, bool);
console.log("Fake message:%s",similarMessage, bool2);
输出:
ECDH Key Exchange, rx, tx
Uint8Array(32) [
67, 47, 133, 36, 228, 190, 228, 192,
193, 16, 142, 142, 25, 97, 124, 2,
4, 210, 194, 51, 29, 25, 148, 70,
50, 30, 215, 107, 154, 52, 19, 180
] Uint8Array(32) [
219, 28, 88, 238, 33, 174, 171, 81,
173, 197, 38, 38, 254, 160, 142, 138,
66, 216, 5, 65, 238, 94, 62, 183,
89, 61, 151, 137, 220, 108, 4, 161
]
Uint8Array(32) [
219, 28, 88, 238, 33, 174, 171, 81,
173, 197, 38, 38, 254, 160, 142, 138,
66, 216, 5, 65, 238, 94, 62, 183,
89, 61, 151, 137, 220, 108, 4, 161
] Uint8Array(32) [
67, 47, 133, 36, 228, 190, 228, 192,
193, 16, 142, 142, 25, 97, 124, 2,
4, 210, 194, 51, 29, 25, 148, 70,
50, 30, 215, 107, 154, 52, 19, 180
]
bobs keys
Uint8Array(32) [
235, 23, 39, 184, 8, 74, 147, 55,
88, 230, 185, 51, 137, 47, 12, 246,
247, 235, 204, 57, 99, 78, 143, 131,
161, 24, 71, 185, 171, 23, 30, 215
] Uint8Array(32) [
79, 224, 52, 64, 235, 231, 82, 236,
10, 169, 210, 156, 249, 182, 60, 27,
173, 160, 150, 31, 8, 20, 217, 215,
58, 172, 185, 230, 185, 185, 67, 0
]
signedMessage: 134,97,230,121,91,96,87,17,1,55,95,20,176,7,203,124,116,236,31,140,173,32,129,206,82,174,214,188,177,45,30,80,230,6,203,204,140,216,228,69,106,134,196,175,95,139,140,116,239,27,235,49,245,24,130,129,154,175,126,127,206,163,206,11,0,0,1,2,128
Real message:0,0,1,2,128 true
Fake message:0,1,1,2,128 false
如您所见,我得到了 bobs 密钥对,但实际上,椭圆曲线主要用于两件事:
1) 对事物进行数字签名
2) 同意对称(AES/ChaCha/Salsa)加密的密钥
请记住,ECC 中的公钥只是曲线上的一个点。
私钥只是一个很大的数字,您可以将其乘以曲线上称为生成器的特殊点的倍数以获取公钥。
此代码代表了我们在生产系统中看到的方法类型,它具有侧通道抗性并使用成熟的库。