简体   繁体   中英

TweetNaCl.js minimal Public-key signatures example

I am trying to understand how to implement a minimal basic Public-key signature example based on the demo located here , using pure javascript.

My research has not yielded a simple javascript example that I can use to understand its inner workings, and the documentation is over my head at the moment.

I tried looking at the source code of the demo, but it is not revealing its secrets.

The library's examples does not have an example for this either.

Cryptography is something very new to me, so any baseline example of how to create their Public-key example with pure javascript in node.js would be greatly appreciated!

Pseudocode-ish:

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?

As a side note, I'm more familiar with node.js require , than I am with ES6 import , if that has any bearing on answers here and could help demonstrate how to use this library.

TweetNaCl.js is a port to JavaScript of TweetNaCl . TweetNacl in turn is a compact implementation of NaCl , which provides various encryption and signature algorithms essentially based on Curve25519 . There are NaCl-compatible implementations or wrappers for many platforms, so that any of these documentations can be used for an introduction, eg the clear documentation of the Libsodium fork.

The documentation of TweetNaCl.js also gives a short overview of the functionality: nacl.sign(message, secretKey) creates a signed message consisting of the 64 bytes signature with attached message. nacl.sign.open(signedMessage, publicKey) verifies the message using the signature and returns the message if verification is successful. The algorithm used for signing is Ed25519 .

As already noted in the comments, you do not distinguish clearly between encryption (purpose: secrecy) and signing (purpose: authentication / integrity). In particular, secrecy of the message is not the purpose of signing. This becomes apparent eg when the return of nacl.sign() contains the unencrypted message (see code snippet below). However, it is true that encryption with the private key is performed during signing (but not for the purpose of keeping it secret).

The following implementation is a pure JavaScript implementation:

 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>

and applies the package tweetnacl-util-js for encoding.

By the way, in the implementation you posted only the Utf8 encoding/decoding was missing:

 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>

Please see the following links for public key encryption and symmetric encryption with TweetNaCl.js. This is about keeping a message secret.

By the way, using the example page( Public-key signatures ) to test the code need to use nacl.sign.detached(message, secretKey) not nacl.sign(msg, secretKey) 😂


reference

TweetNaCl.js Public-key signatures example err

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM