AKushWarrior / steel_crypt

A collection of high-level API's exposing PointyCastle to perform hashing and encrypting in popular/secure algorithms.
https://pub.dev/packages/steel_crypt
Mozilla Public License 2.0
40 stars 10 forks source link

Trying to encryption/decryption data using NodeJs Fails #40

Open arpitjacob opened 3 years ago

arpitjacob commented 3 years ago

Hi I am trying to replicate the same encryption/decryption that is done using Steel Crypt on NodeJs, the same data that is being encrypted on device needs to be decrypted on our server. But using the key to decrypt the data doesn't seem to work.

var aesEncrypter = AesCrypt(padding: PaddingAES.iso78164, key: secureKey);
      var encrypted = aesEncrypter.gcm.encrypt(inp: data, iv: salt);

this is encryption standard I am using.

AKushWarrior commented 3 years ago

To test this, I'll need the values for "secureKey", "data", and "salt". Additionally, what cryptographic library are you using for NodeJS?

arpitjacob commented 3 years ago

I am using the inbuilt library in NodeJs

Here is the code, with the dummy key, salt & data, which works fine on app but on node I am getting an error saying the Invalid key length

var crypto = require('crypto'),
  algorithm = 'aes-256-gcm',
  password = 'n7oAAnS6oSuo9XEExIM2ZfsIw5O1nCuT7JmlEAe+ykQ=',
  // do not use a global iv for production, 
  // generate a new one for each encryption
  iv = 'cfPaa8EXVmNrhfJ36508FQ=='

function encrypt(text) {
  var cipher = crypto.createCipheriv(algorithm, password, iv)
  var encrypted = cipher.update(text, 'utf8', 'hex')
  encrypted += cipher.final('hex');
  var tag = cipher.getAuthTag();
  return {
    content: encrypted,
    tag: tag
  };
}

function decrypt(encrypted) {
  var decipher = crypto.createDecipheriv(algorithm, password, iv)
  decipher.setAuthTag(encrypted.tag);
  var dec = decipher.update(encrypted.content, 'hex', 'utf8')
  dec += decipher.final('utf8');
  return dec;
}

var hw = encrypt("hello world")
  // outputs hello world
console.log(decrypt(hw));
AKushWarrior commented 3 years ago

Your key and iv are using base64 encoding. An issue could be that NodeJS expects a hex-encoded key or something.

AKushWarrior commented 3 years ago

Whoops didnt mean to close this

arpitjacob commented 3 years ago

Actually NodeJs has an option for using Base64 also if convert the key to hex the key length is still wrong

AKushWarrior commented 3 years ago

I don't know what to tell you. 'n7oAAnS6oSuo9XEExIM2ZfsIw5O1nCuT7JmlEAe+ykQ=' is a 32 byte key encoded using base64. What length key does nodeJS want? It should only need a 32 byte key.

arpitjacob commented 3 years ago

Hey, I guess the way I am generating the key could be wrong on my part.

var secureKey = HashCrypt(algo: HashAlgo.Sha_256).hash(inp: 'dummy');

I then used that key for

var aesEncrypter = AesCrypt(padding: PaddingAES.iso78164, key: secureKey);
var encrypted = aesEncrypter.gcm.encrypt(inp: data, iv: salt);

I am just confused why steelcrypt AesCrypt accepted the secureKey if its not 32 byte

And you are right NodeJs needs a 32 byte too but it doesn't accept the key above.

arpitjacob commented 3 years ago

A NodeJs working example similar to the one you've made for dart would be really useful for everyone. It has all the same crypto features which have been standardized and interoperability is really key as a lot of backend software use NodeJs or Python.

arpitjacob commented 3 years ago

for now we decide to stick to

    var crypted = aes.ctr.encrypt(inp: plainText, iv: salt); //encrypt
    var decrypted = aes.ctr.decrypt(enc: crypted, iv: salt);

It works now in both our nodejs backend and dart

arpitjacob commented 3 years ago

I couldn't work out the parameters to make GCM work on node

AKushWarrior commented 3 years ago

Okay. I will investigate the discrepancy between this library and node.

arpitjacob commented 3 years ago

Thanks that would be super helpful

ravitejaavv commented 3 years ago

Okay. I will investigate the discrepancy between this library and node.

Any update on this?