1

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?

  • Could you try an IV size of 12 bytes (the default for GCM) and include an additional parameter to the `createCipheriv` method: ` { authTagLength: 16 }`? Please command below using @maartenbodewes so I can see if this works and answer. – Maarten Bodewes Aug 07 '18 at 14:22
  • @MaartenBodewes I made following changes: `const iv = crypto.randomBytes(12);` `const salt = crypto.randomBytes(16);` `const cipher = crypto.createCipheriv('aes-256-gcm', key, iv, {authTagLength:16});` But I get the same error as above 'Invalid Suite Type' – Shashikant Soni Aug 08 '18 at 05:57
  • 1
    Though I mentioned many details I didn't realise that I had to mention I was trying this in a React App. I searched around and found that the complete crypto package is not imported into a web app by webpack, etc. So many of those ciphers and functions dont work in browser. I was able to run the above code after changing the sizes of key and ivy to be all 16 from the node CLI and also decrypt it. Once I figure out the changes I need for browser I will mention the changes – Shashikant Soni Aug 08 '18 at 09:01
  • What does `crypto.getCiphers()` show? – jas- Mar 22 '19 at 23:58

1 Answers1

1

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.