encrypt icon indicating copy to clipboard operation
encrypt copied to clipboard

5.0.2 cannot decrypt data encoded with 5.0.1

Open alextekartik opened this issue 2 years ago • 38 comments

I get different results since upgrading to 5.0.2. The following test:

import 'package:encrypt/encrypt.dart';
import 'package:test/test.dart';

String encrypt(String decoded, String password) {
  final key = Key.fromUtf8(password);
  final iv = IV.fromLength(16);
  final encrypter = Encrypter(AES(key));
  return encrypter.encrypt(decoded, iv: iv).base64;
}

String decrypt(String encoded, String password) {
  final key = Key.fromUtf8(password);
  final iv = IV.fromLength(16);
  final encrypter = Encrypter(AES(key));
  return encrypter.decrypt(Encrypted.fromBase64(encoded), iv: iv);
}

void main() {
  test('AES encrypt/decrypt', () {
    var password = r'E4x*$TwbkJC-xK4KGC4zJF9j*Rh&WLgR';
    expect(decrypt('amGhyRRLUIoE59IiEys5Vw==', password), 'test');
  });
}

works fine with 5.0.1 but fails with 5.0.2.

package:pointycastle/paddings/pkcs7.dart 42:7                                  PKCS7Padding.padCount
package:pointycastle/padded_block_cipher/padded_block_cipher_impl.dart 112:30  PaddedBlockCipherImpl.doFinal
package:pointycastle/padded_block_cipher/padded_block_cipher_impl.dart 74:25   PaddedBlockCipherImpl.process
package:encrypt/src/algorithms/aes.dart 68:22                                  AES.decrypt
package:encrypt/src/encrypter.dart 39:10                                       Encrypter.decryptBytes
package:encrypt/src/encrypter.dart 50:7                                        Encrypter.decrypt
test/aes_test.dart 15:20                                                       decrypt
test/aes_test.dart 21:12                                                       main.<fn>

Invalid argument(s): Invalid or corrupted pad block

Am I using it wrong ? Unfortunately I have some encrypted content that I cannot read anymore. Thanks !

alextekartik avatar Sep 15 '23 15:09 alextekartik

following, i have the same problem after update

ClevertonZarelli avatar Sep 15 '23 20:09 ClevertonZarelli

Hi, same here. In the mean time I just use hard-coded version in pubspec.yaml: encrypt: 5.0.1 (without ^).

aldycool avatar Sep 16 '23 08:09 aldycool

Same problem

alessandrorisse avatar Sep 16 '23 11:09 alessandrorisse

Can you folks force pointycastle: 3.6.2 to see if it works again, please?

leocavalcante avatar Sep 16 '23 13:09 leocavalcante

Same here.

abinvs-2019 avatar Sep 16 '23 13:09 abinvs-2019

Same, but it's 5.0.2 that is causing the issue. Reverting to 5.0.1 puts things back in order. Interesting gap in updates as 5.0.1 was 2 years ago; 5.0.2 just two days. Great package and hope this gets resolved. Unsure of what (breaking) changes this update provides.

remsysinc avatar Sep 17 '23 00:09 remsysinc

Same issue

idoamram avatar Sep 17 '23 11:09 idoamram

Same issue

mihaieremia avatar Sep 17 '23 15:09 mihaieremia

+1

heshesh2010 avatar Sep 17 '23 21:09 heshesh2010

pointycastle

I overridden to (pointycastle: 3.6.2) and still got same error

heshesh2010 avatar Sep 17 '23 22:09 heshesh2010

I have the same problem

hotplato avatar Sep 18 '23 07:09 hotplato

Same here:

flutter: ^[[38;5;196m[E]^[[0m zoneGuarded: zoneError ERROR: Invalid argument(s): Invalid or corrupted pad b<…> flutter: #0 PKCS7Padding.padCount (package:pointycastle/paddings/pkcs7.dart:42:7) #1 PaddedBlockCipherImpl.doFinal (package:pointycastle/padded_block_cipher/padded_block_cipher_impl.dart:112:30) #2 PaddedBlockCipherImpl.process (package:pointycastle/padded_block_cipher/padded_block_cipher_impl.dart:74:25) #3 AES.decrypt (package:encrypt/src/algorithms/aes.dart:68:22) #4 Encrypter.decryptBytes (package:encrypt/src/encrypter.dart:39:10) #5 Encrypter.decrypt (package:encrypt/src/encrypter.dart:50:7) #6 EncryptionWrapper.decrypt

ivofernandes avatar Sep 18 '23 10:09 ivofernandes

Can you guys force pointycastle: 3.2.0? I think that is the one at the previous version.

leocavalcante avatar Sep 18 '23 12:09 leocavalcante

+1

Constans avatar Sep 18 '23 13:09 Constans

still with error

ClevertonZarelli avatar Sep 18 '23 14:09 ClevertonZarelli

The weird thing is that the files on the stacktrace hasn't changed at those spots:

package:encrypt/src/algorithms/aes.dart 68:22
package:encrypt/src/encrypter.dart 39:10
package:encrypt/src/encrypter.dart 50:7

Can you guys spot any differences?

leocavalcante avatar Sep 18 '23 14:09 leocavalcante

The same problem with the latest 5.0.3 version

flutter: [Invalid argument(s): Invalid or corrupted pad block, #0      PKCS7Padding.padCount (package:pointycastle/paddings/pkcs7.dart:42:7)
#1      PaddedBlockCipherImpl.doFinal (package:pointycastle/padded_block_cipher/padded_block_cipher_impl.dart:112:30)
#2      PaddedBlockCipherImpl.process (package:pointycastle/padded_block_cipher/padded_block_cipher_impl.dart:74:25)
#3      AES.decrypt (package:encrypt/src/algorithms/aes.dart:68:22)
#4      Encrypter.decryptBytes (package:encrypt/src/encrypter.dart:39:10)
#5      Encrypter.decrypt (package:encrypt/src/encrypter.dart:50:7)
#6      Encrypter.decrypt64 (package:encrypt/src/encrypter.dart:66:12)
<asynchronous suspension>

lyskouski avatar Sep 18 '23 15:09 lyskouski

The same problem with the latest 5.0.3 version

5.0.3 fixes another bug. This one wasn't spotted yet.

Help wanted.

leocavalcante avatar Sep 18 '23 16:09 leocavalcante

The weird thing is that what was encrypted with 5.0.2 or 5.0.3 can't be decrypted by the same version of the package (also retroactively - something encrypted with 5.0.1). 5.0.1 can't decode something encoded with 5.0.2 or 5.0.3. The reason is the same mentioned here: https://github.com/leocavalcante/encrypt/issues/314#issuecomment-1723720762. Maybe there is a difference in the Initialization Vector (IV).

Constans avatar Sep 18 '23 19:09 Constans

That is why I think it something at Pointcastle, there wasn't any significative changes at Encrypt, but people are saying that de downgrade didn't work.

leocavalcante avatar Sep 18 '23 19:09 leocavalcante

Downgrade back to 5.0.1 has helped (with encrypted data by 5.0.3 loss)

lyskouski avatar Sep 18 '23 19:09 lyskouski

I mean: the downgrade of the Pointycastle...

leocavalcante avatar Sep 18 '23 19:09 leocavalcante

@farukprogrammer do you know if https://github.com/leocavalcante/encrypt/pull/259 does have something with that somehow?

leocavalcante avatar Sep 18 '23 19:09 leocavalcante

+1

ramvenkat11 avatar Sep 18 '23 20:09 ramvenkat11

Downgrade back to 5.0.1 and clear all data that was encrypted in others version, if you use shared preferences, change the version to automatic clear that. and it back work on this way.

ClevertonZarelli avatar Sep 18 '23 20:09 ClevertonZarelli

I get this error when decrypt data:

Invalid argument(s): Invalid or corrupted pad block

I didn't have this problem before in version 5.0.1. And recently this problem has arisen.

I updated the package to 5.0.2 , 5.0.3 and have the same error

mehdiwaysi avatar Sep 20 '23 08:09 mehdiwaysi

In my specific issue, it turns out that replacing:

final iv = IV.fromLength(16);

by

final iv = IV.allZerosOfLength(16);

fixes my test. i.e. the following test works fine using 5.0.3:

import 'package:encrypt/encrypt.dart';
import 'package:test/test.dart';

String aesEncrypt(String decoded, String password) {
  final key = Key.fromUtf8(password);
  // final iv = IV.fromLength(16); (ok in 5.0.1 not in 5.0.3)
  final iv = IV.allZerosOfLength(16);
  final encrypter = Encrypter(AES(key));
  return encrypter.encrypt(decoded, iv: iv).base64;
}

String aesDecrypt(String encoded, String password) {
  final key = Key.fromUtf8(password);
  // final iv = IV.fromLength(16); (ok in 5.0.1 not in 5.0.3)
  final iv = IV.allZerosOfLength(16);
  final encrypter = Encrypter(AES(key));
  return encrypter.decrypt(Encrypted.fromBase64(encoded), iv: iv);
}

void main() {
  test('AES encrypt/decrypt', () {
    var password = r'E4x*$TwbkJC-xK4KGC4zJF9j*Rh&WLgR';
    expect(aesEncrypt('test', password), 'amGhyRRLUIoE59IiEys5Vw==');
    expect(aesDecrypt('amGhyRRLUIoE59IiEys5Vw==', password), 'test');
  });
}

So it seems that the behavior of IV.fromLength() has changed between the 5.0.1 version (filling with 0) and 5.0.3 (filling with random characters.) Maybe this could be considered as a breaking change as it breaks existing code!

EDIT: The following is compatible for both version:

final iv = IV(Uint8List(16));

However reading the comment:

/// The key is ALL ZEROS - NOT CRYPTOGRAPHICALLY SECURE!
IV.allZerosOfLength(int length)

it sounds that it is not fully secure to use this. What is the correct way to encrypt a content that we need to decrypt later then?. Do we need to save also the content of the iv variable to have it for decryption later?

alextekartik avatar Sep 21 '23 12:09 alextekartik

Hi, @alextekartik. Thank you very much for digging into this.

Ideally, the Initialization Vector should be secured as well: https://en.wikipedia.org/wiki/Initialization_vector

After an issue (https://github.com/leocavalcante/encrypt/issues/246) opened by @InnovativeInventor warning about fromLength implementation being insecure (despite its use was never meant to production, only for tests), @timmaffett helped us (and thanks again for that) solving it at https://github.com/leocavalcante/encrypt/pull/266.

@deskangel warned us about this risk at https://github.com/leocavalcante/encrypt/pull/266#issuecomment-1454848466 and people was asking for the changes: https://github.com/leocavalcante/encrypt/issues/295

Meanwhile I haven't been working with Dart/Flutter anymore, I wasn't using this lib and the support was dropping. I had even renewed my PC and there is nothing of a Dart environment installed, but @JimWuerch helped me at https://github.com/leocavalcante/encrypt/issues/310 on how I could automate the package publishing and voilá.

I assume it is all my fault, I thought that was just a matter of sending a new release and haven't looked carefully to check for breaking changes. My bad, not an excuse, but is really hard to maintain OSS already, then alone and in a stack that you don't work for years, is even harder.


Thank you all for you patience. I'd love to hear especially from you guys that use the package, how we can go from there:

  • Should we move to a major 6.x?
  • You guys just fix with IV.allZerosOfLength(int length)?
  • Any other suggestions?

leocavalcante avatar Sep 21 '23 15:09 leocavalcante

Thanks for the support, I know maintaining open source project is a pain ! You might want to get other contributors/publishers if you cannot commit to it in the the long term as it seems many people are using it ! So you have to maintain it forever, ha ha.

Hard to change the behavior especially in an API that is shown as an example in the README.md.

The safest behavior would be to add a new IV.randomOfLength() API (or whatever better naming), keeping the existing behavior of fromLength (filling with 0) or even deprecating it...Personally I'm fine with fixing it on my side although it might require going through many projects.

alextekartik avatar Sep 21 '23 16:09 alextekartik

hi, @leocavalcante : Thank you very much for you great work!

current state: Encrypted.fromLength(int length) : _bytes = SecureRandom(length).bytes; and Encrypted.fromSecureRandom(int length) : _bytes = SecureRandom(length).bytes;

both (fromLength + from fromSecureRandom) ~~has same implementation~~. (edit: sorry, not true vor IV) Therefore, I suggest just leaving the fromLength implementation as the previous one (5.0.1) and deprecating it for 5.1.0. Also change docs to use fromSecureRandom.

Therefore, we don't have a breaking change with a change in the second level version slot (5.0.1 to 5.0.2).

moodstubos avatar Oct 06 '23 08:10 moodstubos