【问题标题】:How to encrypt and decrypt string/object in nodejs如何在nodejs中加密和解密字符串/对象
【发布时间】:2018-07-24 08:12:00
【问题描述】:

我想加密一个对象然后解密它。加密效果很好,但解密失败。在我的代码下方:

crypto_ext.js

const crypto = require("crypto")
const password = "shared_key"
const algorithm = "aes256"

export const encrypt = (text) => {
    if(!text) return ''
    const cipher = crypto.createCipher(algorithm, password);
    let crypted = cipher.update(text, 'utf-8', 'base64');
    crypted += cipher.final('base64');
    return crypted;
}

export const decrypt = (text) => {
    if(!text) return ''
    const decipher = crypto.createDecipher(algorithm, password);
    let decrypted = decipher.update(text, 'base64', 'utf-8');
    decrypted += decipher.final('utf-8');
    return decrypted;
}

在我的 test.js 中,我有:

import {encrypt, decrypt} from './crypto_ext.js'
let test = {key1: val1, key2: val2}
test = encrypt(JSON.stringify(test)) || test
console.log("Encrypt : ", test)
console.log("Decrypt : ", decrypt(test)) // I should have my object as string here

这就是我得到的错误:

Uncaught Error: unable to decrypt data
at unpad (decrypter.js:83)
at Decipher.webpackJsonp../node_modules/browserify-aes/decrypter.js.Decipher._final (decrypter.js:38)
at Decipher.webpackJsonp../node_modules/cipher-base/index.js.CipherBase._finalOrDigest (index.js:76)
at decrypt (crypto_ext.js:17)
...

你能告诉我我做错了什么吗?

【问题讨论】:

  • 为什么test = encrypt(JSON.stringify(test)) || test 中有|| test
  • 我测试了你的代码并且它有效。

标签: node.js encryption cryptojs node-crypto


【解决方案1】:
  1. 方法createCipher 已弃用。请改用createCipheriv
  2. 尝试使用aes192算法。

【讨论】:

    【解决方案2】:

    依赖:crypto

    您可以使用以下代码实现编解码:-

       const crypto = require('crypto');
            var password = 'ojisdasjdsjabdjs';
            var iv = 'kiamdksndn';
    
            function sha1(input) {
                return crypto.createHash('sha1').update(input).digest();
            }
    
            function password_derive_bytes(password, salt, iterations, len) {
                var key = Buffer.from(password + salt);
                for (var i = 0; i < iterations; i++) {
                    key = sha1(key);
                }
                if (key.length < len) {
                    var hx = password_derive_bytes(password, salt, iterations - 1, 20);
                    for (var counter = 1; key.length < len; ++counter) {
                        key = Buffer.concat([key, sha1(Buffer.concat([Buffer.from(counter.toString()), hx]))]);
                    }
                }
                return Buffer.alloc(len, key);
            }
    
    
            async function encode(string) {
                var key = password_derive_bytes(password, '', 100, 32);
                var cipher = crypto.createCipheriv('aes-256-cbc', key, Buffer.from(iv));
                var part1 = cipher.update(string, 'utf8');
                var part2 = cipher.final();
                const encrypted = Buffer.concat([part1, part2]).toString('base64');
                return encrypted;
            }
    
            async function decode(string) {
                var key = password_derive_bytes(password, '', 100, 32);
                var decipher = crypto.createDecipheriv('aes-256-cbc', key, Buffer.from(iv));
                var decrypted = decipher.update(string, 'base64', 'utf8');
                decrypted += decipher.final();
                return decrypted;
            }
    

    然后调用下面的函数进行编码和解码

    用于编码

    await encode(JSON.stringify({'title': 'some text'}));
    

    用于解码

    await decode('encoded_string_to_decode');
    

    【讨论】:

    • JFYI 得到这个错误:无效的初始化向量
    【解决方案3】:

    尝试使用 'bcrypt' 包,它将帮助您加密密码。 如果要加密数据。然后使用crypto或node-rsa

    链接npm bcrypt package

    Node-RSA

    【讨论】:

    • bcrypt 是密码哈希/KDF,与加密/解密无关。
    • 嘿Shraddha。感谢您的反馈,但此模块对密码加密更有用。我想要做的是首先加密我的字符串并将其作为 URL 中的参数传递,根据这个参数我可以解密它并在其他页面中显示它的内容。
    • 嗨,现在我明白你在这里真正寻找什么了。我简短地阅读了您的描述,因此导致错误的答案。你可以试试 'npmjs.com/package/node-rsa' 这个包 Node RSA 我用来加密和解密我的数据。
    • @MariaMinh 你能告诉我你正在使用哪个包,因为加密现在已被弃用。 Crypto.js 是一个新的
    • @ShraddhaGoel 我使用了 Crypto.js,但我在解密时遇到了另一个错误。我收到“错误:格式错误的 UTF-8 数据”...
    最近更新 更多