I am using dart > encrypt
package in flutter.
I want to do some encryption-decryption logic in web-worker in flutter-web project. I have tried to use crypto-js
package and its vanilla JS https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.2/rollups/aes.js.
I want to verify the results if same encryption and decryption values appear with same key.
I have gone through some solutions in stackoverflow as well but couldn’t find a suitable working which can provide me same generated values.
Following is dart code and its result:
import 'package:encrypt/encrypt.dart';
.
.
final key = Key.fromUtf8("VishnuTestKeyIsHereLongValid32Ch");
final encrypter = Encrypter(AES(key));
final iv = IV.fromLength(16);
var encrypted = encrypter.encrypt("Vishnu", iv: iv);
print(encrypted.base64); // prints 8beisXeeEE055QEPq+kumw==
I am expecting same value to be decrypted from Crypto-js. https://jsfiddle.net/vcgupta/grkexuwz/4/
//html:
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.2/rollups/aes.js"></script>
//js:
var base64Decrypted = '8beisXeeEE055QEPq+kumw=='
var myKey = "VishnuTestKeyIsHereLongValid32Ch"
var result = CryptoJS.AES.decrypt(base64Decrypted, myKey).toString(CryptoJS.enc.Utf8)
console.log(result);
I want to same operations alternatively. Encrypt in javascript and decrypt in dart.
Can anybody help me what I am missing in above solution?
2
Answers
Thanks to @Topaco, his solution worked great.
Here is an encryption-decryption solution compatible to
javascript <-> dart
. Hope it will be helpful for others.Above code encrypt and decrypt perfectly in JS. Below code for same purpose in dart:
The dart code does separately encrypt and decrypts fine. Also it can be done partially in either language.
Dart/encrypt uses CTR mode (aka SIC) and PKCS7 padding by default (i.e. the padding is not implicitly disabled for stream cipher modes). Since you do not specify a mode in the CryptoJS code, the default mode is applied, i.e. CBC (s. here). Thus both codes are incompatible.
Also, in the CryptoJS code, the key must be passed as WordArray (if it is passed as string, a built-in key derivation is used). Additionally, the IV must be passed explicitly (as WordArray). In the Dart code a zero IV (16 0x00 values) is applied.
Furthermore, you should use a newer version of CryptoJS (you are running 3.1.2, the current version is 4.1.1).
Overall, decryption with CryptoJS is:
Keep in mind that a static IV (like a zero IV) is a vulnerability. Instead, a random IV should be used for each encryption, which is passed along with the ciphertext to the decrypting side, usually concatenated (the IV is not secret).
Edit: Because of the bug mentioned in the comment: Test for plaintexts longer than 1 block (16 bytes):