2

I am trying to send encrypted data from my Flutter application to my PHP server, but I am encountering issues with decryption on the PHP server. I am using the Encrypt package in Dart to encrypt the data with the AES encryption algorithm and then sending it to the PHP server, where I am using OpenSSL to decrypt the data.

Here is the Dart code that I am using to encrypt the data:

import 'package:encrypt/encrypt.dart' as encrypt;
void main() async {
   var plainText='test';
   final key = encrypt.Key.fromUtf8('AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA');
   final iv  = encrypt.IV.fromUtf8('AAAAAAAAAAAAAAAA');

   final encrypter = encrypt.Encrypter(encrypt.AES(key));

   final encrypted = encrypter.encrypt(plainText, iv: iv);

   print(encrypted.base64);
}

This code outputs "VBnTmnNX14Sbxqu99PMtWw==".

On the PHP side, I am using the following code to decrypt the data:

// The encrypted string
$encrypted = "VBnTmnNX14Sbxqu99PMtWw==";

// The encryption key and initialization vector (IV)
$key = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA";
$iv = "AAAAAAAAAAAAAAAA";

// Decrypt the string
$decrypted = openssl_decrypt(base64_decode($encrypted), 'AES-192-CBC', $key, OPENSSL_RAW_DATA, $iv);

// Output the decrypted string
echo var_dump($decrypted);

And this outputs "bool(false)" which means the encryption has failed.

Why does it fail, any idea ?

Chris
  • 25
  • 4

1 Answers1

0

The key used is 32 bytes, so AES-256 must be applied on the PHP side. Also, the Dart side automatically uses CTR mode (equivalent to SIC mode, which is the default on the Dart side), requiring AES-256-CTR on the PHP side (instead of AES-192-CBC).

Be aware that the Dart code applies PKCS#7 padding (which is actually not required for a stream cipher mode like CTR). On the PHP side, padding is implicitly disabled for CTR. Therefore, the padding bytes are not removed. The correct fix is to disable padding for CTR on the Dart side (see here, section No/zero padding).

Also note that the key and IV used (as well as a static IV) are vulnerabilities (unless they were chosen that way for testing purposes only).

Topaco
  • 40,594
  • 4
  • 35
  • 62
  • Yes this was the problem by changing the encryption to AES-256-CTR to code worked. Thanks !! :D – Chris Apr 09 '23 at 19:58
  • I have another question since you mentioned the vulnerabilities, since my clients already use the application with this encryption, am i able to change the encryption or will it get me in trouble with the existing files ? (When using encrypt.IV.fromLength(16) i have an iv with 16 0 bytes) – Chris Apr 09 '23 at 20:18
  • @Chris - When the encryption logic is changed, the old data must generally be migrated (decryption with the old logic, re-encryption with the new logic). Note that CTR in conjunction with a static IV (e.g. zero IV) is a serious vulnerability, s. [here](https://crypto.stackexchange.com/q/2991). – Topaco Apr 09 '23 at 21:25
  • @Chris - One approach to avoid this problem is to generate a random IV for each encryption and pass it along with the ciphertext to the decrypting side, usually concatenated (the IV is not a secret), s. e.g. [here](https://stackoverflow.com/q/4951468/9014097). – Topaco Apr 09 '23 at 21:36
  • But when the IV is not a secret why not using a static. The attacker can get the iv from the ciphertext so what is the difference between this or using a static? – Chris Apr 10 '23 at 06:18
  • @Chris - A static IV leads (when using a fixed key, which is usually the case) to a reuse of key-IV pairs making the encryption vulnerable. Look at the references, it is described there. – Topaco Apr 10 '23 at 06:39