1

I am trying to encrypt string in flutter/Dart. I have tried the below code but looks like having IV is mandatory.

final key = Key.fromBase64("Some_Key");
final iv = IV.fromBase64("Some_Key"); // I do not need IV for encryption/decryption

final encrypter = Encrypter(AES(key, mode: AESMode.ecb, padding: 'PKCS7'));
final encrypted = encrypter.encrypt(employeeNumber, iv: iv); //No IV needed

Could someone please let me know how to encrypt and decrypt the strings using AES 256 bit/ ECB mode / PKCS7 padding and without IV.

Please note that I do not need IV at the moment. Kindly help...

Developer
  • 31
  • 1
  • 8
  • What crypto library you are using in Dart and what happens when you just leave out the "iv" parameter (final encrypted = encrypter.encrypt(employeeNumber);) – Michael Fehr Aug 06 '21 at 07:18
  • Seems to be the _encrypt_ package. M. Fehr's way should work. But note that ECB is insecure, better apply a mode with an IV. – Topaco Aug 06 '21 at 07:21
  • @MichaelFehr - I have used encrypt.dart package. I also tried to call the encrypt function without passing IV as you said. But i get the following error - "Unhandled Exception: Bad state: IV is required." – Developer Aug 06 '21 at 07:28
  • @Topaco - Yes I know it's insecure but still this is what I must do now. – Developer Aug 06 '21 at 07:29
  • Mmh, omitting the IV or an `iv: null` doesn't work on my machine either (encrypt 5.0.0). It seems as if an IV must be passed (e.g. a zero IV, `IV.fromLength(16)`), which is then _ignored_ for ECB (maybe a bug). – Topaco Aug 06 '21 at 07:53
  • Yep, check [#211](https://github.com/leocavalcante/encrypt/issues/211). – Topaco Aug 06 '21 at 08:00
  • @Topaco I tried using IV.fromLength(16) and also used the iv which is there in my above code. I both the cases the encrypted string is the same. I am trying to encrypt number 10440. The encrypted string is "5uR51NLAGw4GFc8DPdi29A==". Does this mean that internally for ECB, IV is ignored? – Developer Aug 06 '21 at 08:53
  • @Topaco One more thing I am trying to get a compatible encryption in flutter as in iOS swift. Below is the iOS code. The encrypted string in both ios and flutter are different, let key = encryptionKey let dataBytes : [UInt8] = Array(self.utf8) let keyBytes : [UInt8] = Array(key.utf8) let encryptedData = try AES(key: keyBytes, blockMode: ECB(), padding: .pkcs7).encrypt(dataBytes) let encodedString = Data(encryptedData).base64EncodedString() return encodedString – Developer Aug 06 '21 at 08:54
  • 1
    Since you didn't post an sample key, your ciphertext can't be checked. Yes, the IV is ignored for ECB (which is why you get the same ciphertext for different IVs), see also #211. AES (and ECB) is a standard and platform independent, i.e. it should be compatible with iOS swift (though I'm not familiar with swift). Regarding swift: You should ask another question about this, as it is beyond the scope of this question. – Topaco Aug 06 '21 at 09:00
  • There are a few other higher level cryptographic libraries that have the same issue. I'd use an IV consisting of all zeros. In that case, if it gets XOR'ed with the plaintext, it would still result in the same ciphertext. And it saves a call to the RNG, which may be significantly slower than the encryption itself. – Maarten Bodewes Aug 06 '21 at 12:19
  • Were you able to fix your issue? I am having this same issue with this package. Same code. It keeps throwing error that iv is required and can't be null. Saw the issue mention in comments. Will check it out and use that workaround – kapil Dec 28 '21 at 20:25

2 Answers2

1

I also wanted to avoid IV, and then I found the following solution : Make the dummy IV as

      var ivBtyes = Uint8List.fromList([1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]);
      final iv = encrypt.IV(ivBtyes);

set the AES mode as ECB and padding as "PKCS7". then your code -

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

Though you are passing IV as dummy it will be ignored in ECB mode.

Sohail Ansari
  • 131
  • 1
  • 6
0

For those who are still looking for the answer if you don't have IV value you can use

final iv = IV.fromLength(16);

here is the code that worked

  final iv = IV.fromLength(16);

  final enc = Encrypter(AES(Key(Uint8List.fromList(keyBytes)),
      mode: AESMode.ecb, padding: 'PKCS7'));
  final encrypted = enc.encrypt(plaintext, iv: iv);
  final base64String = base64.encode(encrypted.bytes);
mangesh
  • 574
  • 4
  • 16