Invalid key length in crypto.createCipheriv

34,236

Solution 1

You said you stored a key in BASE 64 and the key is 256 bits (or 32 bytes) (which we see that you computed sha256), so simply get that base64 key, then you can get the bytes easily like this:

const key_in_bytes = Buffer.from(BASE_64_KEY, 'base64')

And you can use this key in bytes as your key as:

const cipher = crypto.createCipheriv('aes-256-ctr', key_in_bytes, iv);

Solution 2

Just add a tip: Key length is dependent on the algorithm, such as for aes192, it's 24 bytes, or aes256, it's 32 bytes. You need to have a key length of 32 byte (256 bit). So if you change your key line to:

let key = crypto.createHash('sha256').update(String(secret)).digest('base64').substr(0, 32);

it will work.

Solution 3

an alternative approach which may be better than chopping the base 64 string into the first 32 bytes is to simply return the value of the key prior to the digest() call:

let key = crypto.createHash('sha256').update(String(secret))

If the key is cut to 32 bytes after converting it into base 64, that chopped string is an invalid base64 string.

Share:
34,236

Related videos on Youtube

user1055010
Author by

user1055010

Updated on June 18, 2021

Comments

  • user1055010
    user1055010 almost 3 years

    I generated a base64-encoded key using this code in NodeJS v8.11.0:

    const secret = 'shezhuansauce';
    const key = crypto.createHash('sha256').update(String(secret)).digest('base64');
    //output is REtgV24bDB7xQYoMuypiBASMEaJbc59nJWChoXbbmsA=
    

    Using the key, I try to encrypt a string:

    var tobeEncrypted = 'some secret string';
    const iv = crypto.randomBytes(16).toString('hex').slice(0, 16);
    const cipher = crypto.createCipheriv('aes-256-ctr', key, iv);
    const encrypted = cipher.update(String(tobeEncrypted), 'utf8', 'hex') + cipher.final('hex');
    console.log(encrypted);
    

    However, I received an error:

    crypto.js:219
    this._handle.initiv(cipher, toBuf(key), toBuf(iv));
               ^
    Error: Invalid key length
    

    The key needs to be base64 string as I will store it in a Cloud service and it only receives base64 string.

    Any help is appreciated.

    • Mijanur Rahman
      Mijanur Rahman almost 3 years
      How I can decrypt in your process?
  • Paul Parker
    Paul Parker over 4 years
    Only answer that doesn't truncate the hash of the secret for no good reason and is extensible to other encoding schemes, e.g. hex, utf8, latin1, ascii, not just base64. Technically, the encoding to base64 can be skipped by using .digest() which will give the Buffer directly.
  • Harry
    Harry almost 4 years
    Although the accepted answer is valid, I prefer this approach better for the reasons mentioned above