I'm trying to implement encrypt/decrypt functions using aes-128-gcm as provided by node crypto. From my understanding, gcm encrypts the ciphertext but also hashes it and provides this as an 'authentication tag'. However, I keep getting the error: "Unsupported state or unable to authenticate data".
I'm not sure if this is an error in my code - looking at the encrypted ciphertext and auth tag, the one being fetched by the decrypt function is the same as the one produced by the encrypt function.
function encrypt(plaintext) {
// IV is being generated for each encryption
var iv = crypto.randomBytes(12),
cipher = crypto.createCipheriv(aes,key,iv),
encryptedData = cipher.update(plaintext),
tag;
// Cipher.final has been called, so no more encryption/updates can take place
encryptedData += cipher.final();
// Auth tag must be generated after cipher.final()
tag = cipher.getAuthTag();
return encryptedData + "$$" + tag.toString('hex') + "$$" + iv.toString('hex');
}
function decrypt(ciphertext) {
var cipherSplit = ciphertext.split("$$"),
text = cipherSplit[0],
tag = Buffer.from(cipherSplit[1], 'hex'),
iv = Buffer.from(cipherSplit[2], 'hex'),
decipher = crypto.createDecipheriv(aes,key,iv);
decipher.setAuthTag(tag);
var decryptedData = decipher.update(text);
decryptedData += decipher.final();
}
The error is being thrown by decipher.final().