NodeJS 节点中aes-128-gcm的“不支持状态或无法验证数据”

relj7zay  于 2022-12-22  发布在  Node.js
关注(0)|答案(2)|浏览(261)

我尝试使用node crypto提供的aes-128-gcm来实现加密/解密函数。据我所知,gcm加密密文,但也散列它,并将其作为一个“authentication tag”提供。然而,我一直收到错误:“不支持的状态或无法验证数据”。
我不确定这是否是代码中的错误-查看加密的密文和auth标记,解密函数获取的密文和加密函数生成的密文是相同的。

function encrypt(plaintext) {
    // IV is being generated for each encryption
    var iv = crypto.randomBytes(12),
        cipher = crypto.createCipheriv(aes,key,iv),
        encryptedData = cipher.update(plaintext),
        tag;

    // Cipher.final has been called, so no more encryption/updates can take place
    encryptedData += cipher.final();

    // Auth tag must be generated after cipher.final()
    tag = cipher.getAuthTag();

    return encryptedData + "$$" + tag.toString('hex') + "$$" + iv.toString('hex');
}

function decrypt(ciphertext) {
    var cipherSplit = ciphertext.split("$$"),
        text = cipherSplit[0],
        tag = Buffer.from(cipherSplit[1], 'hex'),
        iv = Buffer.from(cipherSplit[2], 'hex'),
        decipher = crypto.createDecipheriv(aes,key,iv);

    decipher.setAuthTag(tag);

    var decryptedData = decipher.update(text);

    decryptedData += decipher.final();
}

www.example.com()正在引发错误decipher.final。

af7jpaap

af7jpaap1#

以防万一,如果有人仍然试图得到一个工作的例子,加密和解密过程。
我留下了一些意见,你应该考虑一下。

import * as crypto from 'crypto';

const textToEncode = 'some secret text'; // utf-8
const algo = 'aes-128-gcm';

// Key bytes length depends on algorithm being used:
// 'aes-128-gcm' = 16 bytes
// 'aes-192-gcm' = 24 bytes
// 'aes-256-gcm' = 32 bytes
const key = crypto.randomBytes(16);

const iv = crypto.randomBytes(16);
const cipher = crypto.createCipheriv(algo, key, iv);

const encrypted = Buffer.concat([
  cipher.update(Buffer.from(textToEncode, 'utf-8')),
  cipher.final(),
]);

const authTag = cipher.getAuthTag();

console.info('Value encrypted', {
  valueToEncrypt: textToEncode,
  encryptedValue: encrypted.toString('hex'),
  authTag: authTag.toString('hex'),
});

// It's important to use the same authTag and IV that were used during encoding
const decipher = crypto.createDecipheriv(algo, key, iv);
decipher.setAuthTag(authTag);

const decrypted = Buffer.concat([
  decipher.update(encrypted),
  decipher.final(),
]);

console.info('Value decrypted', {
  valueToDecrypt: encrypted.toString('hex'),
  decryptedValue: decrypted.toString('utf-8'),
});
zwghvu4y

zwghvu4y2#

我设法解决了这个问题:问题是我没有为www.example.com()指定编码类型cipher.final,而是在String中返回它,因此它没有返回decipher.final()所期望的Buffer对象。
为了解决这个问题,我在cipher.update和www.example.com中的“hex”编码参数中添加了“utf-8”cipher.final,在decryption中则相反。

已编辑以添加代码示例-请注意,这是2018年的版本,因此现在可能已经过时。

function encrypt(plaintext) {
    // IV is being generated for each encryption
    var iv = crypto.randomBytes(12),
        cipher = crypto.createCipheriv(aes,key,iv),
         encryptedData = cipher.update(plaintext, 'utf-8', 'hex'),
        tag;

    // Cipher.final has been called, so no more encryption/updates can take place
     encryptedData += cipher.final('hex');

    // Auth tag must be generated after cipher.final()
    tag = cipher.getAuthTag();

    return encryptedData + "$$" + tag.toString('hex') + "$$" + iv.toString('hex');
}

function decrypt(ciphertext) {
    var cipherSplit = ciphertext.split("$$"),
        text = cipherSplit[0],
         tag = Buffer.from(cipherSplit[1], 'hex'),
            iv = Buffer.from(cipherSplit[2], 'hex'),
            decipher = crypto.createDecipheriv(aes, key, iv);

    decipher.setAuthTag(tag);

    var decryptedData = decipher.update(text, 'hex', 'utf-8');

   decryptedData += decipher.final('utf-8');
}

相关问题