Reputation: 398
I tried using aes256,aes-cross, and crypto. But I was not able to decrypt the key which is encrypted using AES 256 (aes-256-ecb) with PKCS7 padding. I ended up with the following mentioned errors.
Error: Invalid key length at Decipheriv.createCipherBase (or) Error: Invalid IV length at Decipheriv.createCipherBase
I was not able to find an npm package that helps me.
Here is the sample code:
const crypto = require("crypto");
//Length of my key is 32
const key = Buffer.from("aaaaaabbbbbbccccccddddddssssssaa", "base64");
//_sek is the encrypted key
const _sek = "NEPkEuWaXZUawBHJZIcMjHJeKuPkaQezuRc3bjWEezlbHzmqCSyh2hazB+WeAJaU"
const cipher = crypto.createDecipheriv(
"aes-256-ecb",
Buffer.from(key, "base64"),
Buffer.from([])
);
return cipher.update(_sek, "base64", "utf8") + cipher.final("utf8");
If anyone could help me with a code-based example in nodejs. It will help me to understand clearly.
Update:
function decrypt(encryted_key, access_key) {
var key = Buffer.from(access_key, "base64");
const decipher = crypto.createDecipheriv("aes-256-ecb", key, "");
decipher.setAutoPadding(false);
var decryptedSecret = decipher.update(encryted_key, "utf8", "base64");
decryptedSecret += decipher.final("base64");
return decryptedSecret;
}
decrypt(
"w2lI56OJ+RqQ04PZb5Ii6cLTxW2bemiMBTXpIlkau5xbmhwP4Qk3oyIydKV1ttWa",
"DvpMLxqKlsdhKe9Pce+dqTdNUnrofuOQPsgmSHhpxF8="
)
Required output: "cdgLxoHvpeMoMd3eXISoMcgQFRxZeMSez5x3F2YVGT4="
But got this : "G7z/eXQefnaeB7mYBq7KDrH+R4LtauNi6AU1v0/yObqoOidSOkIeW085DiMxdCDDjaI+hJiS2JRHDL1fdLrveg="
Thanks in advance.
Upvotes: 1
Views: 3305
Reputation: 319
I couldn't find a viable replacement for setting padding so created my own function which worked for me. Functions below handle padding manually.
const encryptText = (RawText) => {
const cipher = crypto.createCipheriv(DATA_ENCRYPTION_ALGO, KeyBuffer, ivBuffer);
let bufferedRawText = Buffer.from(RawText, 'utf-8');
let totalBlock = Math.ceil(( bufferedRawText.length + 1 ) / 16);
let padding = (totalBlock * 16) - bufferedRawText.length;
let paddigData = []
for(let i = 0; i < padding; i++) {
paddigData.push(Uint8Array.of(padding));
}
const enc = [cipher.update(Buffer.concat([bufferedRawText, Buffer.from(paddigData)]))];
enc.push(cipher.final())
return Buffer.concat(enc).toString('base64');
};
const decryptText = (EncryptedText) => {
const textBytes = Buffer.from(EncryptedText, 'base64');
const decipher = crypto.createDecipheriv(DATA_ENCRYPTION_ALGO, KeyBuffer, ivBuffer);
let dec = Buffer.concat([decipher.update(textBytes), decipher.final()]);
let padding = dec.at(dec.length - 1);
return dec.subarray(0, dec.length - padding).toString('utf-8')
};
Upvotes: 1
Reputation: 49251
The Invalid key length error is caused when the length of the key doesn't match the specified algorithm. E.g. in the posted code aes-256-ecb
is specified, which defines AES-256, i.e. AES with a key length of 32 bytes. However, the key used has a length of only 24 bytes, since it's Base64 decoded when it's read into the buffer. This means that either a 32 bytes key must be used (e.g. if UTF-8 is used as encoding instead of Base64 when reading into the buffer), or AES-192 (specified as aes-192-ecb
).
The Invalid IV length error is caused when an IV is specified in ECB mode (which doesn't use an IV at all), or when in a mode which uses an IV, its length doesn't match the blocksize of the algorithm (e.g. 16 bytes for AES). Since the ECB mode is used here, simply pass null
for the IV (Buffer.from([])
works too).
Example using AES-192 and a 24 bytes key:
const crypto = require("crypto");
const key = "aaaaaabbbbbbccccccddddddssssssaa";
const secret = "01234567890123456789012345678901";
// Encryption
const cipher = crypto.createCipheriv("aes-192-ecb", Buffer.from(key, "base64"), null);
const encryptedSecret = cipher.update(secret, "utf8", "base64") + cipher.final("base64");
console.log(encryptedSecret);
// Decryption
const decipher = crypto.createDecipheriv("aes-192-ecb", Buffer.from(key, "base64"), null);
const decryptedSecret = decipher.update(encryptedSecret, "base64", "utf8") + decipher.final("utf8");
console.log(decryptedSecret);
During decryption, UTF-8 is used as output encoding which is of course only possible if the plaintext is compatible with this, otherwise a suitable encoding such as Base64 has to be applied.
Upvotes: 2