在此沙箱演示中使用Libsodium.js进行简单的Javascript加密 [英] Simple Javascript encryption using Libsodium.js in this sandbox demo
问题描述
我花了很多时间试图让Libsodium.js工作。
I've spent an embarrasing number of hours trying to get Libsodium.js to work.
查看我的小提琴演示 (以及下面粘贴的代码)。
See my fiddle demo (and code pasted below too).
我一直在错误:给定密文的错误密钥
。
我喜欢的是复制这个 PHP示例函数simpleEncrypt($ message,$ key)
进入Libsodium.js。
What I would prefer is to replicate this PHP example of function simpleEncrypt($message, $key)
into Libsodium.js.
但作为首发,我会很高兴甚至可以使用基本的来自Libsodium.js回购的样本来工作。
But as a starter, I'd be happy even getting the basic sample from the Libsodium.js repo to work.
任何提示?
这是代码(也显示在工作小提琴中):
const _sodium = require("libsodium-wrappers");
const concatTypedArray = require("concat-typed-array");
(async () => {
await _sodium.ready;
const sodium = _sodium;
const utf8 = "utf-8";
const td = new TextDecoder(utf8);
const te = new TextEncoder(utf8);
const nonceBytes = sodium.crypto_secretbox_NONCEBYTES;
const macBytes = sodium.crypto_secretbox_MACBYTES;
let key = sodium.from_hex("724b092810ec86d7e35c9d067702b31ef90bc43a7b598626749914d6a3e033ed");
function encrypt_and_prepend_nonce(message, key) {
let nonce = sodium.randombytes_buf(nonceBytes);
var encrypted = sodium.crypto_secretbox_easy(message, nonce, key);
var combined2 = concatTypedArray(Uint8Array, nonce, encrypted);
return combined2;
}
function decrypt_after_extracting_nonce(nonce_and_ciphertext, key) {
if (nonce_and_ciphertext.length < nonceBytes + macBytes) {
throw "Short message";
}
let nonce = nonce_and_ciphertext.slice(0, nonceBytes);
let ciphertext = nonce_and_ciphertext.slice(nonceBytes);
return sodium.crypto_secretbox_open_easy(ciphertext, nonce, key);
}
function encrypt(message, key) {
var x = encrypt_and_prepend_nonce(message, key);
return td.decode(x);
}
function decrypt(nonce_and_ciphertext_str, key) {
var nonce_and_ciphertext = te.encode(nonce_and_ciphertext_str);
return decrypt_after_extracting_nonce(nonce_and_ciphertext, key);
}
var inputStr = "shhh this is a secret";
var garbledStr = encrypt(inputStr, key);
try {
var decryptedStr = decrypt(garbledStr, key);
console.log("Recovered input string:", decryptedStr);
console.log("Check whether the following text matches the original:", decryptedStr === inputStr);
} catch (e) {
console.error(e);
}
})();
推荐答案
哇,我终于搞定了!
真正帮助我的部分是:
Wow, I finally got it working!
The parts that really helped me were:
- https://stackoverflow.com/a/43271130/470749 (
函数u_atob(ascii)
) - 使用
const concatTypedArray = require(concat-typed-array);
- 使用
require(babel-core / register);
和require(babel-polyfill);
,我仍然不明白( https://stackoverflow.com/a/33527883/470749 )
- https://stackoverflow.com/a/43271130/470749 (
function u_atob(ascii)
for Uint8Array) - using
const concatTypedArray = require("concat-typed-array");
- using
require("babel-core/register");
andrequire("babel-polyfill");
, which I still don't understand (https://stackoverflow.com/a/33527883/470749)
这是工作小提琴沙箱。
万一消失,这里是重要的部分:
And in case that ever disappears, here are the important parts:
const nonceBytes = sodium.crypto_aead_xchacha20poly1305_ietf_NPUBBYTES;
let key = sodium.from_hex("724b092810ec86d7e35c9d067702b31ef90bc43a7b598626749914d6a3e033ed");
var nonceTest;
/**
* @param {string} message
* @param {string} key
* @returns {Uint8Array}
*/
function encrypt_and_prepend_nonce(message, key) {
let nonce = sodium.randombytes_buf(nonceBytes);
nonceTest = nonce.toString();
var encrypted = sodium.crypto_aead_xchacha20poly1305_ietf_encrypt(message, null, nonce, nonce, key);
var nonce_and_ciphertext = concatTypedArray(Uint8Array, nonce, encrypted); //https://github.com/jedisct1/libsodium.js/issues/130#issuecomment-361399594
return nonce_and_ciphertext;
}
/**
* @param {Uint8Array} nonce_and_ciphertext
* @param {string} key
* @returns {string}
*/
function decrypt_after_extracting_nonce(nonce_and_ciphertext, key) {
let nonce = nonce_and_ciphertext.slice(0, nonceBytes); //https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/slice
let ciphertext = nonce_and_ciphertext.slice(nonceBytes);
var result = sodium.crypto_aead_xchacha20poly1305_ietf_decrypt(nonce, ciphertext, null, nonce, key, "text");
return result;
}
/**
* @param {string} message
* @param {string} key
* @returns {string}
*/
function encrypt(message, key) {
var uint8ArrayMsg = encrypt_and_prepend_nonce(message, key);
return u_btoa(uint8ArrayMsg); //returns ascii string of garbled text
}
/**
* @param {string} nonce_and_ciphertext_str
* @param {string} key
* @returns {string}
*/
function decrypt(nonce_and_ciphertext_str, key) {
var nonce_and_ciphertext = u_atob(nonce_and_ciphertext_str); //converts ascii string of garbled text into binary
return decrypt_after_extracting_nonce(nonce_and_ciphertext, key);
}
function u_atob(ascii) { //https://stackoverflow.com/a/43271130/
return Uint8Array.from(atob(ascii), c => c.charCodeAt(0));
}
function u_btoa(buffer) { //https://stackoverflow.com/a/43271130/
var binary = [];
var bytes = new Uint8Array(buffer);
for (var i = 0, il = bytes.byteLength; i < il; i++) {
binary.push(String.fromCharCode(bytes[i]));
}
return btoa(binary.join(""));
}
这篇关于在此沙箱演示中使用Libsodium.js进行简单的Javascript加密的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!