Node.js 节点JS解密在Ubuntu服务器上不工作
我有一个可以带钥匙的密码。然后它可以“加密”和“解密”字符串 这就是错误:Node.js 节点JS解密在Ubuntu服务器上不工作,node.js,linux,node-crypto,Node.js,Linux,Node Crypto,我有一个可以带钥匙的密码。然后它可以“加密”和“解密”字符串 这就是错误: 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" | "ae
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");
}
}
}
从“crypto”导入crypto;
导出类型CipherType=“aes-128-gcm”|“aes-128-ccm”|“aes-192-gcm”|“aes-192-ccm”|“aes-256-gcm”|“aes-256-ccm”;
导出类密码{
构造函数(私钥:字符串,私钥配置:{
类型:密码类型,
numAuthTagBytes?:数字,
单位?:数字,
stringBase?:“base64”,
}) {
config.numuthTagBytes=config.numuthTagBytes | | 16;
config.numIvBytes=config.numIvBytes | | 12;
config.stringBase=config.stringBase | |“base64”;
如果(config.numuthTagBytes<16){console.warn(`小心短身份验证标记`);}
如果(config.numIvBytes<12){console.warn(`小心短ivs`);}
}
公共加密(消息:字符串){
const{type,numIvBytes,numAuthTagBytes,stringBase}=this.config;
const iv=加密随机字节(numIvBytes);
常量密码=crypto.createCipheriv(
类型,
缓冲区。从(this.key,stringBase),
四,,
numAuthTagBytes?{'authTagLength':numAuthTagBytes}如有:未定义
);
返回[
iv.toString(stringBase),
密码更新(消息“utf8”,stringBase),
最终密码(stringBase),
(与任何密码相同)。getAuthTag().toString(stringBase)
].加入(“”);
}
公开解密(密文:字符串){
const{type,numIvBytes,numAuthTagBytes,stringBase}=this.config;
让authTagCharLength:number=this.bytesToChars(numuthTagBytes);
设ivCharLength:number=this.bytesToChars(numIvBytes);
const authTag=Buffer.from(cipherText.slice(-authTagCharLength),stringBase);
const iv=缓冲区from(密文切片(0,ivCharLength),stringBase);
const encryptedMessage=Buffer.from(cipherText.slice(ivCharLength,-authTagCharLength),stringBase);
const decipher=crypto.createDecipheriv(
类型,
缓冲区。从(this.key,stringBase),
四,,
{'authTagLength':numuthTagBytes}如有
);
(按任意方式解密)。setAuthTag(authTag);
返回[
解密.更新(加密消息,stringBase,“utf8”),
破译
].加入(“”);
}
专用字节数(numBytes){
if(this.config.stringBase==“base64”){
开关(单位:字节){
案例16:返回24;
案例12:返回16;
案例8:返回12;
案例4:返回8;
案例0:返回0;
默认值:抛出新错误(“这里的数学是什么?”);
}
}否则{
抛出新错误(“TODO:支持其他字符串类型”);
}
}
}
它在本地(MacOS)工作得很好,但在Ubuntu服务器上每次都无法解密
我做错了什么?Linux是否会以不同的方式处理字符串?
编辑:我想我已经发现了问题
node-v
->v8.10.0
Ubuntu通常有一个非常旧的版本NodeJS。您应该更新节点版本:
(拉离)
其中13是您想要的版本(可能应该是最新版本)
# Using Ubuntu
curl -sL https://deb.nodesource.com/setup_13.x | sudo -E bash -
sudo apt-get install -y nodejs