尝试使用crypto在nodejs中解密使用AES 256(AES / ECB / PKCS7Padding)算法生成的加密密钥

问题描述 投票:0回答:2

我尝试使用 aes256、aes-cross 和 crypto。 但我无法解密使用 AES 256 (aes-256-ecb) 和 PKCS7 填充加密的密钥。 我最终遇到了以下提到的错误。

错误:密钥长度无效 在 Decipheriv.createCipherBase (或者) 错误:IV 长度无效 在 Decipheriv.createCipherBase

我找不到对我有帮助的 npm 包。

这是示例代码:

const crypto = require("crypto");
//Length of my key is 32
const key = Buffer.from("aaaaaabbbbbbccccccddddddssssssaa", "base64");
//_sek is the encrypted key
const _sek = "NEPkEuWaXZUawBHJZIcMjHJeKuPkaQezuRc3bjWEezlbHzmqCSyh2hazB+WeAJaU"
const cipher = crypto.createDecipheriv(
    "aes-256-ecb",
    Buffer.from(key, "base64"),
    Buffer.from([])
  );
  return cipher.update(_sek, "base64", "utf8") + cipher.final("utf8");

如果有人可以帮助我在nodejs 中提供基于代码的示例。这将帮助我清楚地理解。

更新:

function decrypt(encryted_key, access_key) {
  var key = Buffer.from(access_key, "base64");
  const decipher = crypto.createDecipheriv("aes-256-ecb", key, "");
  decipher.setAutoPadding(false);
  var decryptedSecret = decipher.update(encryted_key, "utf8", "base64");
  decryptedSecret += decipher.final("base64");
  return decryptedSecret;
}

decrypt(
  "w2lI56OJ+RqQ04PZb5Ii6cLTxW2bemiMBTXpIlkau5xbmhwP4Qk3oyIydKV1ttWa",
  "DvpMLxqKlsdhKe9Pce+dqTdNUnrofuOQPsgmSHhpxF8="
)

所需输出:“cdgLxoHvpeMoMd3eXISoMcgQFRxZeMSez5x3F2YVGT4 =”

但是得到了这个:“G7z/eXQefnaeB7mYBq7KDrH+R4LtauNi6AU1v0/yObqoOidSOkIeW085DiMxdCDDjaI+hJiS2JRHDL1fdLrveg=”

提前致谢。

node.js encryption aes node-crypto aescryptoserviceprovider
2个回答
2
投票

当密钥长度与指定算法不匹配时,会导致无效密钥长度错误。例如。在发布的代码中指定了

aes-256-ecb
,它定义了AES-256,即密钥长度为32字节的AES。然而,所使用的密钥长度只有 24 个字节,因为它在读入缓冲区时是经过 Base64 解码的。这意味着必须使用 32 字节密钥(例如,在读入缓冲区时使用 UTF-8 而不是 Base64 作为编码)或 AES-192(指定为
aes-192-ecb
)。

当在 ECB 模式(根本不使用 IV)中指定 IV 时,或者在使用 IV 的模式下,其长度与块大小不匹配时,会导致IV 长度无效 错误。算法(例如 AES 为 16 字节)。由于此处使用 ECB 模式,因此只需为 IV 传递

null
Buffer.from([])
也可以)。

使用 AES-192 和 24 字节密钥的示例:

const crypto = require("crypto");

const key = "aaaaaabbbbbbccccccddddddssssssaa";
const secret = "01234567890123456789012345678901";

// Encryption
const cipher = crypto.createCipheriv("aes-192-ecb", Buffer.from(key, "base64"), null);
const encryptedSecret = cipher.update(secret, "utf8", "base64") + cipher.final("base64");
console.log(encryptedSecret);

// Decryption
const decipher = crypto.createDecipheriv("aes-192-ecb", Buffer.from(key, "base64"), null);
const decryptedSecret = decipher.update(encryptedSecret, "base64", "utf8") + decipher.final("utf8");
console.log(decryptedSecret);

在解密过程中,使用UTF-8作为输出编码,这当然只有在明文与其兼容的情况下才可能,否则必须应用合适的编码,例如Base64。


0
投票

我找不到设置填充的可行替代品,因此创建了自己的对我有用的函数。下面的函数手动处理填充。

const encryptText = (RawText) => {
    const cipher = crypto.createCipheriv(DATA_ENCRYPTION_ALGO, KeyBuffer, ivBuffer);

    let bufferedRawText = Buffer.from(RawText, 'utf-8');
    let totalBlock = Math.ceil(( bufferedRawText.length + 1 ) / 16);
    let padding = (totalBlock * 16) - bufferedRawText.length;
    let paddigData = []
    for(let i = 0; i < padding; i++) {
    paddigData.push(Uint8Array.of(padding));
    }
    
    const enc = [cipher.update(Buffer.concat([bufferedRawText, Buffer.from(paddigData)]))];
    enc.push(cipher.final())
    return Buffer.concat(enc).toString('base64');
};

const decryptText = (EncryptedText) => {
    const textBytes = Buffer.from(EncryptedText, 'base64');
    const decipher = crypto.createDecipheriv(DATA_ENCRYPTION_ALGO, KeyBuffer, ivBuffer);
    let dec = Buffer.concat([decipher.update(textBytes), decipher.final()]);
    let padding = dec.at(dec.length - 1);
    return dec.subarray(0, dec.length - padding).toString('utf-8')
};
© www.soinside.com 2019 - 2024. All rights reserved.