【问题标题】:How do I encrypt and decrypt a string using node js crypto module?如何使用节点 js 加密模块加密和解密字符串?
【发布时间】:2019-12-20 05:01:39
【问题描述】:

我已经阅读了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() 会返回任何东西,如果update() 也这样做的话。他们的输出有什么区别?我必须调用final吗?我可以继续使用相同的密码吗?


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

【问题讨论】:

  • 一个不简单的加密和解密的东西。根据您要解决的问题,有不同的加密方式。
  • 使用 Ceaser Cipher 加密和解密字符串,我会很高兴的。只需要一个没有工具或密钥就很难破译的字符串。
  • Node 的加密模块适用于较低级别/细粒度的使用。对于具有高级 API 的东西,滚动你自己的辅助函数或使用类似 npmjs.com/package/simple-crypto-js

标签: node.js encryption


【解决方案1】:

确实存在用于此的节点模块 (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));

【讨论】:

    猜你喜欢
    • 2018-02-26
    • 2013-08-13
    • 1970-01-01
    • 2012-07-01
    • 1970-01-01
    • 1970-01-01
    • 2022-11-25
    相关资源
    最近更新 更多