So I have an endpoint where I have to decrypt a key, and based on the information I would return some data or not. The problem is that I always get this error:
TypeError: Invalid initialization vector
at Decipheriv.createCipherBase (node:internal/crypto/cipher:116:19)
at Decipheriv.createCipherWithIV (node:internal/crypto/cipher:135:3)
at new Decipheriv (node:internal/crypto/cipher:289:3)
at createDecipheriv (node:crypto:146:10)
Here is my function to decrypt. The Salt and the IV were concatenated in the begining of the cipher.
import {
createDecipheriv,
pbkdf2Sync,
randomBytes,
createCipheriv,
} from 'crypto';
const keySize = 256;
const derivationIterations = 1000;
decrypt(cipherText: string, passPhrase: string): string {
// Get the complete stream of bytes that represent:
// [32 bytes of Salt] + [32 bytes of IV] + [n bytes of CipherText]
const cipherTextBytesWithSaltAndIv = Buffer.from(cipherText, 'base64');
// Get the saltbytes by extracting the first 32 bytes from the supplied cipherText bytes.
const saltStringBytes = cipherTextBytesWithSaltAndIv.slice(
0,
this.keySize / 8,
);
// Get the IV bytes by extracting the next 32 bytes from the supplied cipherText bytes.
const ivStringBytes = cipherTextBytesWithSaltAndIv.slice(
this.keySize / 8,
(this.keySize / 8) * 2,
);
// Get the actual cipher text bytes by removing the first 64 bytes from the cipherText string.
const cipherTextBytes = cipherTextBytesWithSaltAndIv.slice(
(this.keySize / 8) * 2,
);
const keyBytes = pbkdf2Sync(
passPhrase,
saltStringBytes,
this.derivationIterations,
this.keySize / 8,
'sha1',
);
const decipher = createDecipheriv('aes-256-cbc', keyBytes, ivStringBytes);
const plainTextBytes = Buffer.concat([
decipher.update(cipherTextBytes),
decipher.final(),
]);
return plainTextBytes.toString('utf8');
}
I've tried to create a encryption method, because a thought that I would understand the problem better, but I'm getting the same error
encrypt(plainText: string, passPhrase: string) {
// Salt and IV is randomly generated each time, but is preprended to encrypted cipher text
// so that the same Salt and IV values can be used when decrypting.
const saltStringBytes = randomBytes(this.keySize / 8);
const ivStringBytes = randomBytes(this.keySize / 8).toString('hex');
const plainTextBytes = Buffer.from(plainText, 'utf8');
const password = pbkdf2Sync(
passPhrase,
saltStringBytes,
this.derivationIterations,
this.keySize / 8,
'sha1',
);
const cipher = createCipheriv('aes-256-cbc', password, ivStringBytes);
const encrypted = Buffer.concat([
saltStringBytes,
Buffer.from(ivStringBytes, 'hex'),
cipher.update(plainTextBytes),
cipher.final(),
]);
return encrypted.toString('base64');
}
I actually "translated" this code from a C# one, that uses Rfc2898DeriveBytes and RijndaelManaged.
UPDATE
I've discovered that the C# code was taken from this post
What am I missing?