首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >节点JS decipher.final()抛出“错误的最终块长度”错误

节点JS decipher.final()抛出“错误的最终块长度”错误
EN

Stack Overflow用户
提问于 2020-07-09 11:34:17
回答 2查看 5K关注 0票数 3

我正试图加密/解密。加密工作正常,并将加密数据写入文件。在解密时,我得到了一个长度错误问题。我使用了"utf-8“格式,但错误仍在继续。

代码语言:javascript
复制
/ A decrypt function 
function decrypt(file) {

  let data = JSON.parse(fs.readFileSync(file));

  let iv = Buffer.from(data.iv, 'hex');
  let encryptedText =
    Buffer.from(data.encryptedData, 'hex');


  //  Creating Decipher 
  let decipher = crypto.createDecipheriv(
    algorithm, Buffer.from(key), iv);

  // Updating encrypted text 
  let decrypted = decipher.update(encryptedText);
  let decrypted = Buffer.concat([decrypted, decipher.final()]);

  //  // returns data after decryption 
  return decrypted.toString();
}
代码语言:javascript
复制
//run 
// Decrypts output 
console.log(decrypt('./file.json.enc'));
代码语言:javascript
复制
Error: error:0606506D:digital envelope routines:EVP_DecryptFinal_ex:wrong final block length
    at Decipheriv.final (internal/crypto/cipher.js:170:29)
    at decrypt (/Users/chandrasekarareddy/Documents/projects/encrypt/final.js:48:22)
    at Object.<anonymous> (/Users/chandrasekarareddy/Documents/projects/encrypt/final.js:64:13)
    at Module._compile (internal/modules/cjs/loader.js:959:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:995:10)
    at Module.load (internal/modules/cjs/loader.js:815:32)
    at Function.Module._load (internal/modules/cjs/loader.js:727:14)
    at Function.Module.runMain (internal/modules/cjs/loader.js:1047:10)
    at internal/main/run_main_module.js:17:11 {
  library: 'digital envelope routines',
  function: 'EVP_DecryptFinal_ex',
  reason: 'wrong final block length',
  code: 'ERR_OSSL_EVP_WRONG_FINAL_BLOCK_LENGTH'
}

它在decipher.final()上抛出错误。而不是文件作为输入参数,如果我传递文本,这是错误的罚款。提前感谢

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2020-07-09 13:09:45

如果您收到此错误,很可能是您传入了错误的键。如果密钥被错误地编码到所讨论的文件中,则会发生这种情况。

我建议最好的方法是以十六进制格式编码(因为我们在这里使用JSON )。

下面是对.json.enc文件进行编码的完整示例,然后再进行解码。注意,我使用的是aes-256-cbc,所以如果您更改加密模式,密钥和iv长度可能必须更改。

代码语言:javascript
复制
const crypto = require("crypto");
const fs = require("fs");

function encrypt(buffer, algorithm, key, iv) {
    const cipher = crypto.createCipheriv(algorithm, key, iv);
    return Buffer.concat([cipher.update(buffer, null), cipher.final()]);
}

function decrypt(buffer, algorithm, key, iv) {
    const decipher = crypto.createDecipheriv(algorithm, key, iv);
    return Buffer.concat([decipher.update(buffer), decipher.final()]);
}

function encryptToJsonFile(buffer, filePath, algorithm, key, iv) {
    let encryptedData = encrypt(buffer, algorithm, key, iv);
    let fileData = { encryptedData: encryptedData.toString("hex"), iv: iv.toString("hex") };
    fs.writeFileSync(filePath, JSON.stringify(fileData), "utf8");
    return fileData;
}

function decryptJsonFile(filePath, algorithm, key) {
    let fileData = JSON.parse(fs.readFileSync(filePath, "utf8"));
    let encryptedData = Buffer.from(fileData.encryptedData, "hex");
    let iv = Buffer.from(fileData.iv, "hex");
    return decrypt(encryptedData, algorithm, key, iv);
}

const filePath = "./test.json.enc";
const EncryptionAlgorithm = "aes-256-cbc";

const key = Buffer.from("70ac30ae736068d90467beec0aedd75f3714cfe1e83b030c67911bb649316be0", "hex");
const iv = Buffer.from("3d4be42df33cc6a030aa54df2e144920", "hex");

const textToEncrypt = "My secrets are here";
const bufferToEncrypt = Buffer.from(textToEncrypt, "utf8");

console.log("Encrypted:", encryptToJsonFile(bufferToEncrypt, filePath, EncryptionAlgorithm, key, iv));
console.log("Decrypted:", decryptJsonFile(filePath, EncryptionAlgorithm, key).toString("utf8"));
票数 3
EN

Stack Overflow用户

发布于 2022-08-24 19:42:51

我得到了同样的错误,所以我解释我的解决方案,因为它可能会帮助其他人。

在我的例子中,我对文件进行加密,并将缓冲区(由encrypt()返回)直接存储在s3中。将其转换为JSON。我通过在base64编码字符串(而不是缓冲区)中存储缓冲区来解决这个问题。

createDecipheriv.update()的酷之处在于它接收base64编码的字符串作为输入,并返回解密缓冲区,您可以将其转换为可查看的ascii格式。

让我们看看我的功能:

代码语言:javascript
复制
// this returns buffer, but a buffer can’t be saved in s3 or db (details lost). So always convert 
// it to base64 encoding (which reduces space) and simply give its base64 encoded string 
// output as input to decrypt function as it accepts base64 encoded STRING.
function encrypt(key, buffer) {
  try {
    const cipher = crypto.createCipheriv('aes256', key, resizedIV);
    return Buffer.concat([cipher.update(buffer), cipher.final()]).toString('base64');
  } catch (error) {
    console.log('crypto encrypt err - ', error);
  }
}

这是我的解密函数:

代码语言:javascript
复制
// here cipher text was saved in s3 in base64 format 
// and decipher.update expects an base64 encoded STRING (not buffer)
async function decrypt(key, ciphertext) {
  try {
    const decipher = crypto.createDecipheriv('aes256', key, resizedIV);

    return Buffer.concat([
      decipher.update(ciphertext, 'base64'), // Expect `text` to be a base64 string
      decipher.final(),
    ]).toString();
  } catch (err) {
    console.log('decrypt err - ', err);
  }
}

红利:如果您使用KMS的信封加密从lambda函数中保存dataKey或从lambda函数返回datakey,那么:因为它是一个缓冲区,

在发送/保存缓冲区时,始终将其转换为一个Buffer.from(dataKey).toString('base64')

  • When字符串,例如:Buffer.from(dataKey).toString('base64')

  • When访问/检索该dataKey,将其转换回ascii格式,例如:Buffer.from(base64EncodedData, 'base64').toString('ascii')

如果错误仍然存在,请按以下链接操作:https://mlink.in/qa/?qa=755282/

请让我知道它是否对任何人有帮助:)

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/62813904

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档