Home > Software design >  Image encryption using node.js crypto does not work
Image encryption using node.js crypto does not work

Time:09-26

I created an encryption app using node.js crypto. But the encryption/decryption seems to only work on .txt files. I encrypted an image file, but when i decrypted it, it doesnt return the original image.

const crypto = require("crypto");
const fs = require("fs");
//
function encrypt(text, password) {
  let salt = crypto.randomBytes(16).toString("hex");

  let key = crypto.scryptSync(password, salt, 16, { N: 16384 });
  key = key.toString("hex");

  const cipher = crypto.createCipheriv("aes-256-gcm", key, salt);

  const encrypted = cipher.update(text, "utf8", "hex")   cipher.final("hex");
  const tag = cipher.getAuthTag().toString("hex");

  return salt   tag   encrypted;
}
function decrypt(text, password) {
  const salt = text.substr(0, 32);
  const tag = Buffer.from(text.substr(32, 32), "hex");
  const ciphertext = text.substr(64, text.length);

  let key = crypto.scryptSync(password, salt, 16, { N: 16384 });
  key = key.toString("hex");

  const cipher = crypto.createDecipheriv("aes-256-gcm", key, salt);
  cipher.setAuthTag(tag);
  try {
    let decrypted = cipher.update(ciphertext, "hex", "utf8")   cipher.final("utf8");
    return decrypted;
  } catch (e) {
    return true;
  }
}
//
function encryptFile(fileLocation, password) {
  fs.readFile(fileLocation, "utf8", (err, data) => {
    if (err) return console.log(err);
    if (data) {
      const encText = encrypt(data, password);
      fs.writeFileSync(fileLocation, encText);
      console.log("File Encrypted");
    }
  });
}
function decryptFile(fileLocation, password) {
  fs.readFile(fileLocation, "utf8", (err, data) => {
    if (err) {
      throw err;
    } else {
      const decText = decrypt(data, password);
      if (decText === true) {
        console.log("Wrong Password/Salt");
      } else {
        fs.writeFileSync(fileLocation, decText);
        console.log("File Decrypted");
      }
    }
  });
}
//

const fileLocation = "./sample.txt";
// encryptFile(fileLocation, "password");
decryptFile(fileLocation, "password");

I did it on repl so you can have a look - https://replit.com/@sampauls8520/file-enc I have provided an image file as well so that you can encrypt/decrypt that.

CodePudding user response:

You can't read binary data (this includes images) using the UTF-8 text encoding, nor write them back.

You will need to rework your code so that it doesn't operate on text strings, but with binary buffers.

IOW:

  • don't specify an encoding for fs.readFile/fs.writeFile ("If no encoding is specified, then the raw buffer is returned." say the docs)
  • don't specify either input or output encoding for cipher.update()/cipher.final()
  • Related