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.
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);
}
}
Check out this package for your crypto needs including RSA keys/ciphers.
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:
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
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;
}
© 2022 - 2025 — McMap. All rights reserved.