【问题标题】:having issues in running sample code for public-key cryptography in JS在 JS 中运行公钥加密的示例代码时遇到问题
【发布时间】:2020-09-03 21:36:27
【问题描述】:

JS 新手并试图重现此代码的结果,[1]:bob 为 alice 加密消息。在 [2] 中:Alice 解密消息。私钥/公钥在此处的 [1] 中生成 const bob = nacl.box.keyPair() const alice = nacl.box.keyPair() ,我如何在 [2] 中传递这些键,因为 console.log 不打印这些键?

// reading Alice key pair from secret key
const alice = nacl.box.keyPair.fromSecretKey(/* Uint8Array with 32-byte secret key */)
// reading Bob public key
const bob = {publicKey: /* Uint8Array with 32-byte secret key */}` 

非常感谢您的意见。

[1]

const nacl = require('tweetnacl')
nacl.util = require('tweetnacl-util')

// generating key pairs
const bob = nacl.box.keyPair()
const alice = nacl.box.keyPair()

// generating one time nonce for encryption
const nonce = nacl.randomBytes(24)
// message for Alice
const utf8 = 'Hello Alice'
// Bob encrypts message for Alice
const box = nacl.box(
  nacl.util.decodeUTF8(utf8),
  nonce,
  alice.publicKey,
  bob.secretKey
)

// somehow send this message to Alice
const message = {box, nonce} 

[2]

const nacl = require('tweetnacl')
nacl.util = require('tweetnacl-util')

// reading Alice key pair from secret key
const alice = nacl.box.keyPair.fromSecretKey(/* Uint8Array with 32-byte secret key */)
// reading Bob public key
const bob = {publicKey: /* Uint8Array with 32-byte secret key */}

// const message = ... the message object from Bob
// Alice decrypts message from Bob
const payload = nacl.box.open(message.box, message.nonce, bob.publicKey, alice.secretKey)
const utf8 = nacl.util.encodeUTF8(payload) // <-- 'Hello Alice'

【问题讨论】:

  • 为什么像这样使用公钥加密只需要传递公钥
  • 嗯,我如何访问它?当我这样做console.log(bob.publickey) 时,它会打印 'undefined' 。
  • 好吧,我给你一个完整的答案

标签: javascript encryption cryptography public-key-encryption


【解决方案1】:

所以,

我不知道你的代码为什么不工作,但它可能在某个地方出错。

我在应用加密领域工作,我写了下面的例子来帮助你。

tweetnacl 很好,但在生产系统中你应该使用libsodium 之类的东西。

我写的这段代码展示了如何在 libsodium 的 JS 绑定中执行 elliptic curve Diffie-HellmanEdDSA 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 中的公钥只是曲线上的一个点。 私钥只是一个很大的数字,您可以将其乘以曲线上称为生成器的特殊点的倍数以获取公钥。

此代码代表了我们在生产系统中看到的方法类型,它具有侧通道抗性并使用成熟的库。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-19
    • 1970-01-01
    • 1970-01-01
    • 2020-05-06
    相关资源
    最近更新 更多