简体   繁体   中英

How to Decrypt encrypted text in Flutter/Dart

We have this code on encrypting/decrypting a particular message and I'd like to decrypt the value in Flutter (dart).

/
 * Encrypt text
 * @param text
 */
export const encrypt = (text: string): string => {
  const encJson = CryptoJS.AES.encrypt(JSON.stringify(text), SECRET_KEY).toString();
  return CryptoJS.enc.Base64.stringify(CryptoJS.enc.Utf8.parse(encJson));
};

/
 * Decrypt text
 * @param ciphertext
 */
export const decrypt = (ciphertext: string): string => {
  const decData = CryptoJS.enc.Base64.parse(ciphertext).toString(CryptoJS.enc.Utf8);
  const bytes = CryptoJS.AES.decrypt(decData, SECRET_KEY).toString(CryptoJS.enc.Utf8);
  return JSON.parse(bytes);
};

I have tried the example mentioned in this article but could not make it work. https://medium.com/@chingsuehok/cryptojs-aes-encryption-decryption-for-flutter-dart-7ca123bd7464

I really appreciate if anyone can help or point me out on what to change on my code.

Current code:


String decryptAESCryptoJS(String encrypted, String passphrase) {
  try {
    Uint8List encryptedBytesWithSalt = base64.decode(encrypted);

    Uint8List encryptedBytes =
        encryptedBytesWithSalt.sublist(16, encryptedBytesWithSalt.length);
    final salt = encryptedBytesWithSalt.sublist(8, 16);
    var keyndIV = deriveKeyAndIV(passphrase, salt);
    final key = encrypt.Key(keyndIV.item1);
    final iv = encrypt.IV(keyndIV.item2);
    final encrypter = encrypt.Encrypter(
        encrypt.AES(key, mode: encrypt.AESMode.cbc, padding: "PKCS7"));
    final decrypted =
        encrypter.decrypt64(base64.encode(encryptedBytes), iv: iv);
    return decrypted;
  } catch (error) {
    throw error;
  }
}

Tuple2<Uint8List, Uint8List> deriveKeyAndIV(String passphrase, Uint8List salt) {
  var password = createUint8ListFromString(passphrase);
  Uint8List concatenatedHashes = Uint8List(0);
  List<int> currentHash = Uint8List(0);
  bool enoughBytesForKey = false;
  Uint8List preHash = Uint8List(0);

  while (!enoughBytesForKey) {
    int preHashLength = currentHash.length + password.length + salt.length;
    if (currentHash.length > 0)
      preHash = Uint8List.fromList(currentHash + password + salt);
    else
      preHash = Uint8List.fromList(password + salt);

    currentHash = md5.convert(preHash).bytes;
    concatenatedHashes = Uint8List.fromList(concatenatedHashes + currentHash);
    if (concatenatedHashes.length >= 48) enoughBytesForKey = true;
  }

  var keyBtyes = concatenatedHashes.sublist(0, 32);
  var ivBtyes = concatenatedHashes.sublist(32, 48);
  return new Tuple2(keyBtyes, ivBtyes);
}

Uint8List createUint8ListFromString(String s) {
  var ret = new Uint8List(s.length);
  for (var i = 0; i < s.length; i++) {
    ret[i] = s.codeUnitAt(i);
  }
  return ret;
}

Uint8List genRandomWithNonZero(int seedLength) {
  final random = Random.secure();
  const int randomMax = 245;
  final Uint8List uint8list = Uint8List(seedLength);
  for (int i = 0; i < seedLength; i++) {
    uint8list[i] = random.nextInt(randomMax) + 1;
  }
  return uint8list;
}

The CryptoJS code unnecessarily Base64 encodes the ciphertext twice during encryption. So the most reasonable solution would be to fix the CryptoJS code.
In encrypt() , encJson is already the Base64 encoded ciphertext, ie the body of the encrypt() method should actually be:

return CryptoJS.AES.encrypt(JSON.stringify(text), SECRET_KEY).toString(); 

and analogously the body of decrypt() :

const bytes = CryptoJS.AES.decrypt(ciphertext, SECRET_KEY).toString(CryptoJS.enc.Utf8);
return JSON.parse(bytes);

With this fix, successful decryption with the unmodified Dart code is possible.


If for some reason the CryptoJS code must not be changed, the Dart code in decryptAESCryptoJS() must also Base64 decode twice:

Uint8List encryptedBytesWithSalt = base64.decode(utf8.decode(base64.decode(encrypted)));

With this fix, the ciphertext of the unmodified CryptoJS code can be successfully decrypted.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM