Reputation: 15
I have some code that does encrypts and decrypts a string using node crypto; however, when I pass in a different authTag into the decipher.setAuthTag, it still decrypts succesfully. I was wondering if this is the expected behavior. If not, what would be the proper way to authenticate the text has not been tampered with?
Standard Encryption:
const { createCipheriv, randomBytes, createDecipheriv } = require("crypto");
const text = "hello world";
const iv = randomBytes(16); // Initialization vector
const secret_key = Buffer.from(
"2ef08b673cff8759d7df0546e8ff273415e072237c81c192ebe52ac1b10eb684",
"hex"
);
const cipher = createCipheriv("aes-256-gcm", secret_key, iv);
let encrypted = cipher.update(text, "utf8", "hex");
encrypted += cipher.final("hex");
const authTag = cipher.getAuthTag().toString("hex");
const encryptedString = `${iv.toString("hex")}:${encrypted}:${authTag}`;
Standard Decryption:
const [iv_dcrypt, encrypted_dcrypt, authTag_dcrypt] =
encryptedString.split(":");
const decipher = createDecipheriv(
"aes-256-gcm",
secret_key,
Buffer.from(iv_dcrypt, "hex")
);
// Using a different auth tag
decipher.setAuthTag(Buffer.from(`${authTag_dcrypt}7`, "hex"));
let decrypted = decipher.update(encrypted_dcrypt, "hex", "utf8");
try {
decrypted += decipher.final("utf8");
} catch (err) {
console.log(err);
console.log("Authentication failed");
}
console.log(decrypted); // No error is thrown and original message is shown
Upvotes: 0
Views: 93