Reputation: 248
Hi, I would like to have an example of AES encryption and decryption with Dart. I saw in Dart there are a library cipher
https://www.dartdocs.org/documentation/cipher/0.3.0/cipher.api/cipher.api-library.html
that can help to do that. But I have 2 problems here :
An simple example of encrypting a string, and decrypt it to get the initial string.
I need it to work with other AES library, assuming that they all follow the standard. In particular I have my frontend in Dart and backend in C++ which I plan to use crypto++ for that purpose. The point is in crypto++, the required input are the key and the Initialization Vector (IV), while in Dart/cipher, it doesn't seem to require the IV. I wonder if the input requirement are different, they couldn't work together.
Conclusion, if someone can help with an example of using Dart with any library (cipher/crypto) that can encrypt/decrypt a string with 2 inputs Key and IV, that will amazingly help me.
Thank you all
Upvotes: 2
Views: 3385
Reputation: 544
For anyone coming here now, I wrote a custom package based off PointyCastle and written entirely in Dart which can greatly simplify AES for you.
https://pub.dev/packages/steel_crypt
It looks something like this implemented:
var FortunaKey = CryptKey().genFortuna(); //generate 32 byte key with Fortuna //you can also enter your own
var iv = CryptKey().genDart(16); //generate iv for AES with Dart Random.secure() //you can also enter your own
var aesEncrypter = AesCrypt(FortunaKey, 'cbc', 'pkcs7'); //generate AES CBC block encrypter with key and PKCS7 padding
String encrypted = aesEncrypter.encrypt('somedatahere', iv); //encrypt
String decrypted = aesEncrypter.decrypt(encrypted, iv); //decrypt
This solves any issues with inputs that may have occurred earlier.
Upvotes: 0
Reputation: 248
I finally get my encryption decryption example work, so I answer to my question. The easiest way is to use Salsa20 algorithm, then transform everything to hex string before serialize and send it.
Below is the code encrypt/decrypt without sending through the network.
import "dart:typed_data";
import 'dart:convert';
import "package:cipher/cipher.dart";
import "package:cipher/impl/base.dart";
Uint8List StringToUint8List( String s ) {
var ret = new Uint8List(s.length);
for( var i=0 ; i<s.length ; i++ ) {
ret[i] = s.codeUnitAt(i);
}
return ret;
}
/// UTF16 Decoding
String Uint8ListToString( Uint8List ui ) {
String s = new String.fromCharCodes(ui);
return s;
}
void main() {
initCipher();
final testStr = "Hello, i am a very very very very very very very very long string, please encrypte me";
final ivStr = "2urPAr4H"; // Need to have size 8
final keyStr = "QuJuesMhcssE4e8Q4Kt1XCJW3tcpzcEI"; // Need to have size 32
final _ivEncoded = UTF8.encode(ivStr);
final _keyEncoded = UTF8.encode(keyStr);
final _key = new KeyParameter(_keyEncoded);
final params = new ParametersWithIV(_key,_ivEncoded);
var cipher = new StreamCipher( "Salsa20" );
cipher..reset()..init( true, params );
var encryptedEncodedData = cipher.process( StringToUint8List(testStr) );
var encryptedDataStr = Uint8ListToString(encryptedEncodedData);
cipher..reset()..init( false, params );
var dencryptedEncodedData = cipher.process( StringToUint8List(encryptedDataStr) );
var dencryptedDataStr = Uint8ListToString(dencryptedEncodedData);
//expect(testStr, dencryptedDataStr);
}
Upvotes: 2
Reputation: 94018
I'm not going to supply a complete sample code, but if you want to use Dart crypto, you should be going with counter mode (CTR) encryption, simply because that seems to be the only actual AES cipher mode implemented by Dart.
CTR is also called SIC mode and the implementation can be found here. It helpfully uses a ParametersWithIV
. If you would use a non-randomized nonce you should place it at the high order (leftmost, starting with byte index 0, as CTR mode is usually big endian) end of the IV.
Upvotes: 3