在此沙箱演示中使用Libsodium.js进行简单的Javascript加密 [英] Simple Javascript encryption using Libsodium.js in this sandbox demo

查看:106
本文介绍了在此沙箱演示中使用Libsodium.js进行简单的Javascript加密的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我花了很多时间试图让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 (function u_atob(ascii) for Uint8Array)
  • using const concatTypedArray = require("concat-typed-array");
  • using require("babel-core/register"); and require("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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆