help icon indicating copy to clipboard operation
help copied to clipboard

Unable to decrypt aes-128-cbc

Open markg85 opened this issue 2 years ago • 3 comments

Version

17.6.0

Platform

4.14.180-3-ARCH nodejs/node#1 SMP PREEMPT Sat Jun 5 22:29:47 UTC 2021 armv7l GNU/Linux

Subsystem

crypto

What steps will reproduce the bug?

The export lines are for clarity to see how i generate the key and iv.

export AES_KEY=$(openssl rand -hex 16)
export AES_IV=$(openssl rand -hex 16)
openssl enc -d -aes-128-cbc -K $AES_KEY -iv $AES_IV -in <encrypted_data> -out <decrypted_data>

Now if this were real keys and real data then this decryption step would've worked just fine.

In nodejs this seems to be either impossible to do or is hidden extremely well in the documentation where i can't find it.Crypto does claim it supports it (aes-128-cbc is in the getCiphers() function on the crypto object).

In nodejs i try this:

let key = '115f3d8d51ed3ecd9633fd9c8aa9de25'
let iv = '3f42550dc722917ac8eae5dd613c52b1'
let decipher = crypto.createDecipheriv('aes-128-cbc', key, iv);

This downright fails with:

code: 'ERR_CRYPTO_INVALID_IV'

It gives me no hints whatsoever to give me a clue what a good length would be. Note that with these very same key and iv openssl works just fine.

Now i tried a bit more bit more brute force testing (keep changing till it works...) I cannot get aes-128-cbc working with any length IV.

Next i tried aes-256-cbc Same key and iv as above. Also:

code: 'ERR_CRYPTO_INVALID_IV'

Again with brute force trying... This finally worked:

let key = '115f3d8d51ed3ecd9633fd9c8aa9de25'
let iv = '3f42550dc722917a'

How often does it reproduce? Is there a required condition?

Every single time

What is the expected behavior?

Work like openssl.

What do you see instead?

code: 'ERR_CRYPTO_INVALID_IV'

Additional information

I don't know what i'm doing wrong or why it doesn't work. I'm following the documentation for this but it is written in in kinda generic wording. In other terms, it doesn't help me at all. It also doesn't help that there is absolutely 0 mention of proper length IV for a given cipher. That on it's own would be a nice improvement.

In general i do think this should work. It probably can work, but i just don't know how.

More verbose call stack output (it does show me the error code) would be tremendously helpful too. Like add a description that actually tells you why it crashed! Invalid IV is really generic.

markg85 avatar Mar 09 '22 01:03 markg85

I'm facing the same issue

ObaidQatan avatar Jun 16 '22 08:06 ObaidQatan

Hi, it turned out that iv may not always be 16 bits, which leads to such an error...probably. The solution is to convert them into some unit type like Buffer. Try this out:

const key = Buffer.from('115f3d8d51ed3ecd9633fd9c8aa9de25','hex');
const iv = Buffer.from('3f42550dc722917a','hex');
const cipher = crypto.createCipheriv('aes-256-cbc', secret, iv);

this should work.

ObaidQatan avatar Jun 17 '22 05:06 ObaidQatan

Hi, it turned out that iv may not always be 16 bits, which leads to such an error...probably. The solution is to convert them into some unit type like Buffer. Try this out:

const key = Buffer.from('115f3d8d51ed3ecd9633fd9c8aa9de25','hex');
const iv = Buffer.from('3f42550dc722917a','hex');
const cipher = crypto.createCipheriv('aes-256-cbc', secret, iv);

this should work.

I tried your snippet, still have the same error 'ERR_CRYPTO_INVALID_IV'

Azleal avatar Aug 01 '22 02:08 Azleal

Facing the same issue here.

crazyoptimist avatar Mar 08 '23 22:03 crazyoptimist

Facing the same issue here.

Can you mention the steps to reproduce the error?

ObaidQatan avatar Mar 09 '23 19:03 ObaidQatan

const ENCRYPT_IV = '115f3d8d51ed3ecd9633fd9c8aa9de25'
const ENCRYPT_IS = '3f42550dc722917ac8eae5dd613c52b1'

const initVector = Buffer.from(ENCRYPT_IV, 'utf-8')
const securitykey = Buffer.from(ENCRYPT_IS, 'utf-8')
const algorithm = 'aes-128-cbc'
const cipher = crypto.createCipheriv(algorithm, securitykey, initVector)

This produces the same error, and I don't know why.

crazyoptimist avatar Mar 09 '23 19:03 crazyoptimist

Can you mention details like, node version, crypto version etc.

const ENCRYPT_IV = '115f3d8d51ed3ecd9633fd9c8aa9de25'
const ENCRYPT_IS = '3f42550dc722917ac8eae5dd613c52b1'

const initVector = Buffer.from(ENCRYPT_IV, 'utf-8');
const securitykey = Buffer.from(ENCRYPT_IS, 'utf-8');
const cipher = crypto.createCipheriv(algorithm, securitykey, initVector);

This produces the same error, and I don't know why. Can you mention details like what node and crypto versions you are using

ObaidQatan avatar Mar 09 '23 19:03 ObaidQatan

Node v18.12.1

crypto version follows the node version right?

crazyoptimist avatar Mar 09 '23 20:03 crazyoptimist

Node v18.12.1

crypto version follows the node version right?

You will find it in your package.json

ObaidQatan avatar Mar 09 '23 20:03 ObaidQatan

No, there isn't.

Read what this says: https://www.npmjs.com/package/crypto

crazyoptimist avatar Mar 09 '23 20:03 crazyoptimist

const ENCRYPT_IV = '115f3d8d51ed3ecd9633fd9c8aa9de25'
const ENCRYPT_IS = '3f42550dc722917ac8eae5dd613c52b1'

const initVector = Buffer.from(ENCRYPT_IV, 'utf-8');
const securitykey = Buffer.from(ENCRYPT_IS, 'utf-8');
const cipher = crypto.createCipheriv(algorithm, securitykey, initVector);

This produces the same error, and I don't know why.

which algorithm are you using?

ObaidQatan avatar Mar 09 '23 20:03 ObaidQatan

This issue is about aes-128-cbc. I use the same. Updated my original comment.

crazyoptimist avatar Mar 09 '23 20:03 crazyoptimist

Try generate the key and vector as follows and let me know:

const algorithm = 'aes-128-cbc'; 
const key = crypto.randomBytes(16); 
const iv = crypto.randomBytes(16);

const cipher = crypto.createCipheriv(algorithm, key, iv);

ObaidQatan avatar Mar 09 '23 20:03 ObaidQatan

Works perfect for me. Thanks!

crazyoptimist avatar Mar 09 '23 20:03 crazyoptimist

@markg85 is the issue resolved? if yes, close this as resolved.

ObaidQatan avatar Mar 09 '23 20:03 ObaidQatan

@markg85 did this issue persist? If not, you may close it as resolved.

ObaidQatan avatar Apr 18 '24 22:04 ObaidQatan

@ObaidQatan While the issue is solved, the error - when you run into it - is still vague. https://nodejs.org/api/crypto.html#using-strings-as-inputs-to-cryptographic-apis notes some caveats for using strings as IV and KEY. Ultimately creating a Buffer from a string as hex (your example) works but that's non-obvious from the documentation.

I think the docs and API should just omit (and deprecate) the use of strings directly and instead just suggest to use the buffer object.

markg85 avatar Apr 18 '24 22:04 markg85