如何使用Node JS加密模块加密和解密字符串?

时间:2019-12-19 18:43:23

标签: node.js encryption

我已经读过the docs,但是发生的事情比我看到的任何原因还要多。所以要么我做错了,要么设计比必要的复杂。我正在寻找两个基本功能:

const key = "my_secret_key";
const encrypted = encrypt("secret", key);
const decrypted = decrypt(encrypted, key);

到目前为止,这是我所拥有的,但是它不起作用,并且很难启动:

const Encrypt = createCipheriv("aes-128-ccm", ENV.jwt_secret, null);
const Decrypt = createDecipheriv("aes-128-ccm", ENV.jwt_secret, null);

let encrypted = Encrypt.update("secret") + "" + Encrypt.final();
let decrypted = Decrypt.update(encrypted) + "" + Decrypt.final(); // throws error about not liking strings

我了解更新缓冲区的想法...但是我没有缓冲区。而且我似乎无法弄清楚为什么final()也返回任何内容。他们的输出之间有什么区别?我是否必须打入决赛?我可以继续使用相同的密码吗?


如何使用Node js加密模块简单地加密/解密字符串?

1 个答案:

答案 0 :(得分:0)

确实存在

个节点模块(https://www.npmjs.com/package/simple-crypto-js),但是它们在定制方面没有提供太多功能。另外,我也不喜欢导入模块,该模块可能只是项目中粘贴100行文件的副本。

@Saptarshi Basu提供了此链接(stackoverflow.com/a/53573115/1235935)。我基本上只是复制了该代码,并做了一些对我正在使用的密码类型有效的工作,并且只需很少的工作就可以完成其余的工作。

是的,希望对您有所帮助:

import crypto from "crypto";


export type CipherType = "aes-128-gcm" | "aes-128-ccm" | "aes-192-gcm" | "aes-192-ccm" | "aes-256-gcm" | "aes-256-ccm";

export function createKeyForCipher(cipherType: CipherType): string {
    let numBytes: number;
    switch (cipherType) {
        case "aes-128-gcm": numBytes = 128 / 8; break;
        default: throw new Error(`TODO: support cipherType "${cipherType}"`);
    }
    return crypto.randomBytes(numBytes).toString("base64");
}

export class Cipher {
    constructor(private key: string, private config: {
        type: CipherType,
        numAuthTagBytes?: number,
        numIvBytes?: number,
        stringBase?: "base64",
    }) {
        config.numAuthTagBytes = config.numAuthTagBytes || 16;
        config.numIvBytes = config.numIvBytes || 12;
        config.stringBase = config.stringBase || "base64";
        if (config.numAuthTagBytes < 16) { console.warn(`Be careful of short auth tags`); }
        if (config.numIvBytes < 12) { console.warn(`Be careful of short ivs`); }
    }


    public encrypt(msg: string) {
        const {type, numIvBytes, numAuthTagBytes, stringBase} = this.config;
        const iv = crypto.randomBytes(numIvBytes);
        const cipher = crypto.createCipheriv(
            type,
            Buffer.from(this.key, stringBase),
            iv,
            { 'authTagLength': numAuthTagBytes } as any
        );

        return [
            iv.toString(stringBase),
            cipher.update(msg, "utf8", stringBase),
            cipher.final(stringBase),
            (cipher as any).getAuthTag().toString(stringBase)
        ].join("");
    }


    public decrypt(cipherText: string) {
        const {type, numIvBytes, numAuthTagBytes, stringBase} = this.config;
        let authTagCharLength: number = 24; // TODO: compute from numAuthTagBytes and stringBase
        let ivCharLength: number = 16; // TODO: compute from numIvBytes and stringBase

        const authTag = Buffer.from(cipherText.slice(-authTagCharLength), stringBase);
        const iv = Buffer.from(cipherText.slice(0, ivCharLength), stringBase);
        const encryptedMessage = Buffer.from(cipherText.slice(ivCharLength, -authTagCharLength), stringBase);

        const decipher = crypto.createDecipheriv(
            type,
            Buffer.from(this.key, stringBase),
            iv,
            { 'authTagLength': numAuthTagBytes } as any
        );
        (decipher as any).setAuthTag(authTag);

        return [
            decipher.update(encryptedMessage, stringBase, "utf8"),
            decipher.final()
        ].join("");
    }
}

// ----------------------- Usage -----------------

const keyIn = createKeyForCipher("aes-128-gcm");
console.log(keyIn);
const cipher = new Cipher(keyIn, {
    type: "aes-128-gcm"
});
const encrypted = cipher.encrypt("This is some string to encrypt");
console.log(encrypted + "");
console.log(cipher.decrypt(encrypted));