Node JS 解密无法在 Ubuntu 服务器上运行
Node JS decipher not working on Ubuntu server
我有一个可以使用密钥的密码器。然后它可以 "encrypt" 和 "decrypt" 字符串。
这是错误:
Error: Unsupported state or unable to authenticate data
0|ts-node | at Decipheriv.final (crypto.js:183:26)
这是我的实现:
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 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,
numAuthTagBytes ? { 'authTagLength': numAuthTagBytes } as any : undefined
);
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 = this.bytesToChars(numAuthTagBytes);
let ivCharLength: number = this.bytesToChars(numIvBytes);
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("");
}
private bytesToChars(numBytes) {
if (this.config.stringBase === "base64") {
switch (numBytes) {
case 16: return 24;
case 12: return 16;
case 8: return 12;
case 4: return 8;
case 0: return 0;
default: throw new Error("What's the math here?");
}
} else {
throw new Error("TODO: support other string types");
}
}
}
它在本地 (MacOS) 运行良好,但在 Ubuntu 服务器上它每次都无法解密。
我做错了什么? Linux 是否可能以不同方式对待字符串?
编辑:我想我已经找到问题 node -v
-> v8.10.0
Ubuntu 通常有一个非常旧的 NodeJS 版本。您应该更新您的节点版本:
(来自 https://askubuntu.com/a/548776/461996)
# Using Ubuntu
curl -sL https://deb.nodesource.com/setup_13.x | sudo -E bash -
sudo apt-get install -y nodejs
其中 13 是您想要的版本(可能应该是最新版本)
我有一个可以使用密钥的密码器。然后它可以 "encrypt" 和 "decrypt" 字符串。
这是错误:
Error: Unsupported state or unable to authenticate data
0|ts-node | at Decipheriv.final (crypto.js:183:26)
这是我的实现:
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 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,
numAuthTagBytes ? { 'authTagLength': numAuthTagBytes } as any : undefined
);
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 = this.bytesToChars(numAuthTagBytes);
let ivCharLength: number = this.bytesToChars(numIvBytes);
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("");
}
private bytesToChars(numBytes) {
if (this.config.stringBase === "base64") {
switch (numBytes) {
case 16: return 24;
case 12: return 16;
case 8: return 12;
case 4: return 8;
case 0: return 0;
default: throw new Error("What's the math here?");
}
} else {
throw new Error("TODO: support other string types");
}
}
}
它在本地 (MacOS) 运行良好,但在 Ubuntu 服务器上它每次都无法解密。
我做错了什么? Linux 是否可能以不同方式对待字符串?
编辑:我想我已经找到问题 node -v
-> v8.10.0
Ubuntu 通常有一个非常旧的 NodeJS 版本。您应该更新您的节点版本:
(来自 https://askubuntu.com/a/548776/461996)
# Using Ubuntu
curl -sL https://deb.nodesource.com/setup_13.x | sudo -E bash -
sudo apt-get install -y nodejs
其中 13 是您想要的版本(可能应该是最新版本)