I have encrypted in flutter using dart library encrypt. Below is the code sample:
import 'package:encrypt/encrypt.dart' as enc;
final key = enc.Key.fromUtf8('Thisisasamplekeythatamusinginmyc'); //32 chars
final iv = enc.IV.fromUtf8('thisismysampleiv');//16 chars
String encryptMyData(String text) {
final e = enc.Encrypter(enc.AES(key));
final encrypted_data = e.encrypt(text, iv: iv);
return encrypted_data.base64;
}
I am able to encrypt and the issue arises when i try to decrypt the code using this code on javascript using Crypto JS:
const cryptkey = CryptoJS.enc.Utf8.parse('Thisisasamplekeythatamusinginmyc');
const crypted = CryptoJS.enc.Base64.parse("fdsUYHdv/5PoJSoZGwWppw==");
var decrypt = CryptoJS.AES.decrypt({ciphertext: crypted}, cryptkey, {
iv: CryptoJS.enc.Hex.parse('thisismysampleiv'),
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7
});
console.log(decrypt.toString(CryptoJS.enc.Utf8));
The challenge is it always returns empty string even using the AES.js library.
I have looked at this answer but same issue exists.
Any help is appreciated.
CodePudding user response:
The CryptoJS code is incomaptible because the IV is decoded incorrectly. Instead of the Hex encoder, the Utf8 encoder must be used.
Also, the encrypt library applies the CTR mode by default. Therefore, in the CryptoJS code the CTR mode must be used instead of the CBC mode:
const cryptkey = CryptoJS.enc.Utf8.parse('Thisisasamplekeythatamusinginmyc');
const cryptiv = CryptoJS.enc.Utf8.parse('thisismysampleiv')
// Decryption
const crypted = CryptoJS.enc.Base64.parse("fdsUYHdv/5PoJSoZGwWppw==");
var decrypt = CryptoJS.AES.decrypt({ciphertext: crypted}, cryptkey, {
iv: cryptiv,
mode: CryptoJS.mode.CTR
});
console.log(decrypt.toString(CryptoJS.enc.Utf8));
// Encryption
var encrypt = CryptoJS.AES.encrypt("Sample Text", cryptkey, {
iv: cryptiv,
mode: CryptoJS.mode.CTR
});
console.log(encrypt.toString())
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.1.1/crypto-js.min.js"></script>
Usually no padding is used for a stream cipher mode like CTR. Note that both libraries apply PKCS#7 padding by default and do not automatically disable it for a stream cipher mode. Therefore, the padding should be explicitly disabled on both sides (with padding: null
on the Dart side and padding: CryptoJS.pad.NoPadding
on the CryptoJS side).
Alternatively, a block cipher mode like CBC can be used on both sides. Then, padding must be applied (e.g. PKCS#7).
If a static IV is used beyond testing and a password for the key: Then, for security reasons, a key derivation function such as PBKDF2 should be applied. Also, for each encryption, a random IV should be generated, which is passed to the other side along with the ciphertext (typically concatenated).