NodeJS aes gcm invalid suite type error

1.6k Views Asked by At

I am trying to use default crypto package from node and encrypt some data using aes-256-gcm mode.

The code looks like below:

var crypto = require('crypto');

function encrypt() {
   var sessionKey = Buffer.from(crypto.randomBytes(32));
   const iv = crypto.randomBytes(16);
   const key = crypto.pbkdf2Sync(sessionKey, salt, 1000, 32, 'sha512');
   const cipher = crypto.createCipherIv('aes-256-gcm', key, iv);
    ......
}

I get an error while trying to initialize the cipher as shown above. The error is:

encrypter.js:77 Uncaught TypeError: invalid suite type
    at Object.createCipheriv (encrypter.js:77)

I changed the cipher to aes-256-cbc to test and that works fine. So I feel that GCM mode may not be working because of the OpenSSL on my machine. I did check and seems to be fine. I tried using the id-aes256-GCM name but still get the same error.

My environment looks like below:

node -v:   v10.8.0

openssl version : LibreSSL 2.2.7

I tried to lookup the available ciphers using below command

openssl list-cipher-algorithms

The list contains: id-aes128-GCM, id-aes192-GCM, id-aes256-GCM

I also checked openssl enc --help and it has the gcm commands listed with different names:

Valid ciphername values:
-aes-128-gcm
-aes-192-gcm
-aes-256-gcm

PS: I am not sure if these different values mean anything different.

Am kind of new to Node so would be great if you can point me to where the problem could be.

Edit: Looking at the JS console at the line where it fails. The crypto code is as follows:

var modelist = {
  ECB: require('./modes/ecb'),
  CBC: require('./modes/cbc'),
  CFB: require('./modes/cfb'),
  OFB: require('./modes/ofb'),
  CTR: require('./modes/ctr')
};
module.exports = function (crypto) {
  function createCipheriv(suite, password, iv) {
    var config = modes[suite];
    if (!config) {
      throw new TypeError('invalid suite type');
    }

So I am guessing that the GCM is not supported or loaded by crypto with these configs?

1

There are 1 best solutions below

0
On

As I mentioned in the comment above. I was trying to use 'crypto' package from a React App and its not included in the final package file when webpack builds a single package.js file. So to solve that I had to install the browserify version of crypto

npm install crypto-browserify --save

and import the cipher capabilities separately.

const mycrypto = require('crypto')
var aes = require('browserify-aes')

The final code that works (only changes) is:

const iv = mycrypto.randomBytes(16);
const key = mycrypto.pbkdf2Sync(sessionKey, salt, 1000, 32, 'sha512');
const cipher = aes.createCipherIv('aes-256-gcm', key, iv);

The hashing and randombytes etc functions are still to be used from crypto package. Only the cipher functions come from the browserified package.

Thanks @Maarten for the suggestion on iv size and authTag option.