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