AES crypto decrypt error: 'ERR_OSSL_EVP_WRONG_FINAL_BLOCK_LENGTH'

Issue

I am trying to decrypt data from mongodb using key and iv which was stored in env function to retrieve data, but I am getting this error:

ERR_OSSL_EVP_WRONG_FINAL_BLOCK_LENGTH

app.get("/recieve", async(req, res) => {
  try {
    const data = await UploadData.find();

    const decryptedData = data.map((item) => {
      const decryptedFullName = decryptData(item.fullname, secretKey);
      const decryptedCatName = decryptData(item.catName, secretKey);
      const decryptedEmail = decryptData(item.email, secretKey);
      const decryptedContact = decryptData(item.contact, secretKey);
      const decryptedLocation = decryptData(item.location, secretKey);

      return {
        ...item.toObject(),
        fullname: decryptedFullName,
        catName: decryptedCatName,
        email: decryptedEmail,
        contact: decryptedContact,
        location: decryptedLocation,
      };
    });
    res.json(decryptedData);
  } catch (error) {
    console.error("Error fetching data:", error);
    res.status(500).json({
      error: "Internal server error"
    });
  }
});

Function to decrypt data:

function decryptData(encryptedData, key) {
  try {
    const buff = Buffer.from(encryptedData, "base64");
    encryptedData = buff.toString("utf-8");
    var decipher = crypto.createDecipheriv("aes-256-cbc", key, iv);
    return (
      decipher.update(encryptedData, "base64", "utf8") +
      decipher.final("utf8")
    );
  } catch (error) {
    console.log("Error decrypting data:", error);
    return null;
  }
}

The data is being encrypted like this:

function encryptData(data, key, iv) {
  const keyBuffer = Buffer.from(key, "hex");
  const cipher = crypto.createCipheriv("aes-256-cbc", keyBuffer, iv);

  let encryptedData = cipher.update(data, "utf8", "base64") + cipher.final("base64");
  return encryptedData;
}

Solution

This conversion you’re trying to here:

encryptedData = Buffer.from(encryptedData, "base64").toString("utf-8")

damages your data (irreversibly). Pass the Base64 encoded data encryptedData directly to update(), see here. If this doesn’t work your data is inconsistent (wrong key, wrong IV, corrupted ciphertext etc.)
The credit to this answer belongs to Topaco

The correct method would be like this:

const crypto = require("crypto");

const key = "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f";
const keyBuffer = Buffer.from(key, "hex");
const iv = Buffer.from("202122232425262728292a2b2c2d2e2f", "hex");
const data = "The quick brown fox jumps over the lazy dog";

// Encryption
const cipher = crypto.createCipheriv("aes-256-cbc", keyBuffer, iv);
var encryptedData = cipher.update(data, "utf8", "base64") + cipher.final("base64");
console.log(encryptedData);

// Decryption
const decipher = crypto.createDecipheriv("aes-256-cbc", keyBuffer, iv);
//encryptedData = Buffer.from(encryptedData, "base64").toString("utf-8"); // this line corrupts your data
const decryptedData = decipher.update(encryptedData, "base64", "utf8") + decipher.final("utf8");
console.log(decryptedData);

Answered By – MoeezMahmood Ramay

This Answer collected from stackoverflow, is licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply

(*) Required, Your email will not be published