node.js - 错误:不支持的状态或无法验证数据
我在运行以下代码时遇到了下面的错误。
错误:不支持的状态或无法在 Decipheriv.final (node:internal/crypto/cipher:196:29) 中验证数据 在 decrypt (/Users/username/dev/playground/node/src/index.ts:14:65)
import crypto from "crypto";
const key = "13312156329479471107309870982123";
const encrypt = (message: string): string => {
const iv = crypto.randomBytes(16);
const cipher = crypto.createCipheriv("aes-256-gcm", key, iv);
return `${cipher.update(message, "utf-8", "hex")}${cipher.final("hex")}`;
};
const decrypt = (message: string): string => {
const iv = crypto.randomBytes(16);
const decipher = crypto.createDecipheriv("aes-256-gcm", key, iv);
return `${decipher.update(message, "hex", "utf-8")}${decipher.final(
"utf-8"
)}`;
};
console.log(decrypt(encrypt("hello")));
我已经读过这些帖子
- 在 Node 中使用 aes-128-gcm 时出现“状态不支持或无法验证数据”
- 在 Node.js 解密时出现错误(错误:不支持的状态或无法验证数据)
但我不认为我遇到相同的错误是出于相同的原因。任何帮助都将不胜感激。谢谢
答案#1
iv 需要在加密和解密中都通用。应该阅读文档
const key = crypto.randomBytes(32);
const iv = crypto.randomBytes(16);
const encrypt = (message: string): string => {
const cipher = crypto.createCipheriv("aes-256-cbc", key, iv);
return `${cipher.update(message, "utf-8", "hex")}${cipher.final("hex")}`;
};
const decrypt = (message: string): string => {
const decipher = crypto.createDecipheriv("aes-256-cbc", key, iv);
return `${decipher.update(message, "hex", "utf-8")}${decipher.final(
"utf-8"
)}`;
};
答案#2
对我来说,我也在使用gcm;我不确定这是否与此有关。
最终,对我有效的方法是 getAuthTag 和 setAuthTag。
我需要将我的数据存储为一个简单的字符串,所以有很多在 hex 和其他格式之间转换的操作。由于这些数据要存入数据库,我还必须存储 iv,现在还有 authTag,所以我只是用 | 来分隔这些部分。
例子
import * as crypto from 'crypto'
const key = crypto
.createHash('sha256')
.update(String(process.env.ENCRYPTION_KEY))
.digest('base64')
.substring(0, 32)
const cipherAlgorithm = 'aes-256-gcm'
export class PropertiesEncryption {
static encrypt(str: string): string {
const initVector = crypto.randomBytes(16)
const initVectorHex = initVector.toString('hex')
const cipher = crypto.createCipheriv(cipherAlgorithm, key, initVector)
const encoded = cipher.update(str, 'utf-8', 'hex') + cipher.final('hex')
const authTag = cipher.getAuthTag().toString('hex')
const metaAndEncoded = [authTag, initVectorHex, encoded].join('|')
return metaAndEncoded
}
static decrypt(str: string): string {
const [authTag, initVectorHex, encrypted] = str.split('|')
const initVector = Buffer.from(initVectorHex, 'hex')
const decipher = crypto.createDecipheriv(cipherAlgorithm, key, initVector)
decipher.setAuthTag(Buffer.from(authTag, 'hex'))
const decrypted =
decipher.update(encrypted, 'hex', 'utf-8') + decipher.final('utf-8')
return decrypted
}
}
