TweetNaCl.js 最小公钥签名示例
Posted
技术标签:
【中文标题】TweetNaCl.js 最小公钥签名示例【英文标题】:TweetNaCl.js minimal Public-key signatures example 【发布时间】:2021-02-21 22:21:55 【问题描述】:我试图了解如何基于位于here 的演示,使用纯 javascript 实现一个最小的基本公钥签名示例。
我的研究还没有产生一个简单的 javascript 示例,我可以用它来了解它的内部工作原理,而 documentation 此刻让我头疼。
我尝试查看演示的source code,但它并没有透露它的秘密。
图书馆的examples 也没有这方面的例子。
密码学对我来说是非常新的东西,因此任何关于如何在 node.js 中使用纯 javascript 创建其公钥示例的基线示例都将不胜感激!
伪代码:
const nacl = require('tweetnacl')
let message = "This is my unencrypted message"
let naclPair = nacl.sign.keyPair()
let signedMessage = nacl.sign(message, naclPair.secretKey)
let decrypted = nacl.sign.open(signedMessage, naclPair.publicKey) // is this right?
console.log(decrypted) // should this print the decrypted message?
附带说明,我对 node.js require
比对 ES6 import
更熟悉,如果这对这里的答案有任何影响,并且可以帮助演示如何使用这个库。
【问题讨论】:
只要看一下他们 GitHub 上的示例和 README,似乎是对的,是的。但请注意,在签署消息时,它不是“加密的”,而是“签名的”。如果你想学习密码学,我建议你从它背后的数学开始,然后在 C 中实现一些东西。这应该对数学有最大的透明度。祝你好运! @Victor 我很欣赏你的评论。我正在寻找如何在无需学习 C 的情况下将 TweetNaCL.js 库与 javascript 一起使用,因为这就是库存在的原因。我只需要正确的推动才能让它发挥作用。 有人可以帮忙吗? 【参考方案1】:TweetNaCl.js 是 TweetNaCl 的 JavaScript 端口。 TweetNacl 又是NaCl 的一个紧凑实现,它提供了基本上基于Curve25519 的各种加密和签名算法。许多平台都有与 NaCl 兼容的实现或包装器,因此这些文档中的任何一个都可以用于介绍,例如Libsodium fork 的清晰文档。
TweetNaCl.js 的文档还简要概述了该功能:nacl.sign(message, secretKey)
创建一个签名消息,该消息由 64 字节签名和附加消息组成。 nacl.sign.open(signedMessage, publicKey)
使用签名验证消息,如果验证成功则返回消息。用于签名的算法是Ed25519。
正如 cmets 中已经指出的,您没有清楚地区分加密(目的:保密)和signing(目的:身份验证/完整性)。特别是,消息的保密性不是签名的目的。这变得很明显,例如当nacl.sign()
的返回包含未加密的消息时(参见下面的代码 sn-p)。但是,在签名过程中确实会使用私钥进行加密(但不是为了保密)。
以下实现是纯 JavaScript 实现:
var keyPair = nacl.sign.keyPair();
var secretKey = keyPair.secretKey;
var publicKey = keyPair.publicKey;
var msgStr = "The quick brown fox jumps over the lazy dog";
var msg = nacl.util.decodeUTF8(msgStr);
var signature = nacl.sign(msg, secretKey);
var signatureB64 = nacl.util.encodeBase64(signature);
console.log(signatureB64.replace(/(.64)/g,'$1\n')); // Display signature plus message (Base64 encoded)
var signatureMsgPart = signature.slice(64);
console.log(nacl.util.encodeUTF8(signatureMsgPart)); // Display message from nacl.sign() return value: signing is not for encryption!
var verifiedMsg = nacl.sign.open(signature, publicKey);
console.log(nacl.util.encodeUTF8(verifiedMsg)); // Display message after successfull verification
<script src="https://cdn.jsdelivr.net/npm/tweetnacl-util@0.15.0/nacl-util.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/tweetnacl@1.0.1/nacl.min.js"></script>
并应用包tweetnacl-util-js进行编码。
顺便说一句,在您发布的实现中,仅缺少 Utf8 编码/解码:
let message = "This is my unencrypted message"
let naclPair = nacl.sign.keyPair()
let signedMessage = nacl.sign(nacl.util.decodeUTF8(message), naclPair.secretKey)
let decrypted = nacl.sign.open(signedMessage, naclPair.publicKey) // is this right? -> Yes
console.log(nacl.util.encodeUTF8(decrypted)) // should this print the decrypted message? -> Yes, but the 'verified' message is printed!
<script src="https://cdn.jsdelivr.net/npm/tweetnacl-util@0.15.0/nacl-util.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/tweetnacl@1.0.1/nacl.min.js"></script>
请使用 TweetNaCl.js 查看 public key encryption 和 symmetric encryption 的以下链接。这是关于对消息保密。
【讨论】:
完美,谢谢!我此时的意图只是为了消息的完整性。【参考方案2】:顺便说一句,使用示例页面(Public-key signatures)测试代码需要使用nacl.sign.detached(message, secretKey)
而不是nacl.sign(msg, secretKey)
?
参考
TweetNaCl.js Public-key signatures example err
【讨论】:
以上是关于TweetNaCl.js 最小公钥签名示例的主要内容,如果未能解决你的问题,请参考以下文章