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()