5

As the title suggests, I would like to know if there is a way to encrypt and decrypt, using for example the RSA algorithm, data from javascript to dart and the opposite. I saw that there is a library, 'js', which allows you to use javascript code in dart but I was not able to use it for what I need. I tried also to use various libraries provided for both languages ​​to perform these encryption operations but they are not compatible between the two languages.

4 Answers 4

5

Keygen (NodeJS)

Docs: https://nodejs.org/api/crypto.html#crypto_crypto_generatekeypair_type_options_callback

const { generateKeyPair } = require('crypto');

generateKeyPair('rsa', {
    modulusLength: 4096,    // key size in bits
    publicKeyEncoding: {
        type: 'spki',
        format: 'pem',
    },
    privateKeyEncoding: {   
        type: 'pkcs8',      
        format: 'pem',
    },
}, (err, publicKey, privateKey) => {
    // Handle errors and use the generated key pair.
});

NodeJS encryption via JSEncrypt library

node-jsencrypt: https://www.npmjs.com/package/node-jsencrypt
JSEncrypt: https://travistidwell.com/jsencrypt/#

const JSEncrypt = require('node-jsencrypt');  

function encrypt(text, key) {
    const crypt = new JSEncrypt();
    crypt.setKey(key);
    return crypt.encrypt(text);
}

function decrypt(encrypted, privateKey) {
    const crypt = new JSEncrypt();
    crypt.setPrivateKey(privateKey);
    return crypt.decrypt(encrypted);
}

Dart encryption via crypton

GitHub: https://github.com/konstantinullrich/crypton

import 'package:crypton/crypton.dart';

import 'encryption.dart';

class AsymmetricCrypt implements Encryption {
  final String _key;
  RSAPublicKey _publicKey;
  RSAPrivateKey _privateKey;

  AsymmetricCrypt._(this._key);

  @override
  String encrypt(String plain) {
    _publicKey ??= RSAPublicKey.fromPEM(_key);
    return _publicKey.encrypt(plain);
  }

  @override
  String decrypt(String data) {
    _privateKey ??= RSAPrivateKey.fromPEM(_key);
    return _privateKey.decrypt(data);
  }
}
Sign up to request clarification or add additional context in comments.

2 Comments

Wow, thank you so much, I've been looking for so long for a full response. This works perfectly with NodeJS and Flutter.
Where is the file import 'encryption.dart';?? Don´t reference in the example code...
1

Check out this package for your crypto needs including RSA keys/ciphers.

1 Comment

i saw the pointycastle package(dart) and cryptoJS (NodeJS) but i don't know how i can merge pointycastle with cryptoJS
1

Symmetric Javascript - Flutter/Dart compatible encryption package.

This was a beneficial post & helped me with Asymmetric as above.

I am creating a hybrid crypto system, here is what I played around with to get the symmetric version working:

Package

Docs

Implementation help I got

Flutter Package- SteelCrypt

The code is rough but it basically shows all the encoding required on the JS end to get proper output on the Flutter end. Flutter end is a piece of cake AS LONG AS YOU GET THE ENCODING RIGHT IN JS ;)

Implementation encryption in Javascript:

var CryptoJS = require("crypto-js");
  try {
    var JsonFormatter = {
  stringify: function(cipherParams) {
    // create json object with ciphertext
    var jsonObj = { ct: cipherParams.ciphertext.toString(CryptoJS.enc.Base64) };

    // optionally add iv or salt
    if (cipherParams.iv) {
      jsonObj.iv = cipherParams.iv.toString();
    }

    // stringify json object
    return JSON.stringify(jsonObj);
  },
  parse: function(jsonStr) {
    // parse json string
    var jsonObj = JSON.parse(jsonStr);

    // extract ciphertext from json object, and create cipher params object
    var cipherParams = CryptoJS.lib.CipherParams.create({
      ciphertext: CryptoJS.enc.Base64.parse(jsonObj.ct)
    });

    // optionally extract iv or salt

    if (jsonObj.iv) {
      cipherParams.iv = CryptoJS.enc.Hex.parse(jsonObj.iv);
    }

    return cipherParams;
  }
};

var encrypted = CryptoJS.AES.encrypt("Message", "Secret Passphrase", {
  format: JsonFormatter
});
var decrypted = CryptoJS.AES.decrypt(encrypted, "Secret Passphrase", {
  format: JsonFormatter
});
decrypted.toString(CryptoJS.enc.Utf8);

    return {
    "key": CryptoJS.enc.Base64.stringify(encrypted.key),
    "iv": CryptoJS.enc.Base64.stringify(encrypted.iv),
    "encrypted": CryptoJS.enc.Base64.stringify(encrypted.ciphertext),
    "decrypted": decrypted.toString(CryptoJS.enc.Utf8),
  }
  } catch (error) {
    throw new Error(error);
  }

Returns

{
key: Y4GKaFmHD9fPBh/LI04nooA3WVoBWSIkd0GzqJkX7fA=,
iv: DlNlgIv+Vboxq8MSrIFtVA==,
encrypted: NduRQJ7CB40r18w4meeIoQ==,
decrypted: Message
}

Flutter/Dart implementation:

//AES CBC decryption from Parse CryptoJS
  var iv = 'DlNlgIv+Vboxq8MSrIFtVA==';
  var key = 'Y4GKaFmHD9fPBh/LI04nooA3WVoBWSIkd0GzqJkX7fA=';
  var cypher = AesCrypt(key: key, padding: PaddingAES.pkcs7);
  var encryptedData = 'NduRQJ7CB40r18w4meeIoQ==';
  print(cypher.cbc.decrypt(enc: encryptedData, iv: iv)); //decrypt

Prints

Message

Comments

1

You can use the 'aescryptojs' package on the flutter side and 'crypto-js' on the node.js side. This way the AES algorithms will work consistently on both client and sever side.

Flutter:

class DataEncrypt {
  static wrappingEncrypted(dynamic data) {
    // Todo: datanin sifrelenmesi islemi
    final unencryptedData = data;
    final key = '${dotenv.env['ENCRYPT_KEY']}';
    final encryptedData = encryptAESCryptoJS(unencryptedData, key);
    print("Encrypted data :" + encryptedData);
    return encryptedData;
  }

  static wrappingDescrypted(dynamic data) {
    // Todo: sifrenin cozumlenmesi islemi
    final key = '${dotenv.env['ENCRYPT_KEY']}';
    final descryptedData = decryptAESCryptoJS(data, key);
    print("Descrypted data :" + descryptedData);
    return descryptedData;
  }
}

Node.js:

function funcDecryptedData(data) {
    // Todo: AES Decrypted
    var bytes = CryptoJS.AES.decrypt(data, process.env.ENCRYPT_KEY);
    var descryptedData = bytes.toString(CryptoJS.enc.Utf8);
    return descryptedData;
}
function funcEncryptedData(data) {
    //Todo: AES Encrypted
    var encryptedData = CryptoJS.AES.encrypt(data, process.env.ENCRYPT_KEY).toString();
    return encryptedData;
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.