leocavalcante / encrypt

🔒 A set of high-level APIs over PointyCastle for two-way cryptography.
BSD 3-Clause "New" or "Revised" License
345 stars 140 forks source link

fernet always return "Fernet key must be 32 url-safe base64-encoded bytes." #184

Open fuadarradhi opened 3 years ago

fuadarradhi commented 3 years ago

after upgrade to v4.1.0, always return error "Fernet key must be 32 url-safe base64-encoded bytes."

but tested with 4.0.1 and 4.0.2 work fine...

ramtinq commented 3 years ago

Same Here. Tested your Fernet example code and it gives the error "Fernet key must be 32 url-safe base64-encoded bytes.".

leocavalcante commented 3 years ago

Would be nice to have a small snippet that reproduces the error.

ramtinq commented 3 years ago

the exact copy of the package's example for fernet reproduces the error:

`import 'package:encrypt/encrypt.dart'; import 'dart:convert';

void main() { final plainText = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit'; final key = Key.fromUtf8('my32lengthsupersecretnooneknows1'); final iv = IV.fromLength(16);

final b64key = Key.fromUtf8(base64Url.encode(key.bytes)); // if you need to use the ttl feature, you'll need to use APIs in the algorithm itself final fernet = Fernet(b64key); final encrypter = Encrypter(fernet);

final encrypted = encrypter.encrypt(plainText); final decrypted = encrypter.decrypt(encrypted);

print(decrypted); // Lorem ipsum dolor sit amet, consectetur adipiscing elit print(encrypted.base64); // random cipher text print(fernet.extractTimestamp(encrypted.bytes)); // unix timestamp } `

This error starts showing up in versions newer than 4.0.2 .

ramosmarco commented 3 years ago

Hi,

With these changes the package's example works, I encrypt in dart and decrypt in python without problem, but it was tested with very few keys, so be careful.

Changes: final key = 'my32lengthsupersecretnooneknows1__4L11NlqU0='; final b64key = Key.fromBase64(key);

Example void main() { final plainText = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit'; final key = 'my32lengthsupersecretnooneknows1__4L11NlqU0='; final iv = IV.fromLength(16);

final b64key = Key.fromBase64(key); // if you need to use the ttl feature, you'll need to use APIs in the algorithm itself final fernet = Fernet(b64key); final encrypter = Encrypter(fernet);

final encrypted = encrypter.encrypt(plainText); final decrypted = encrypter.decrypt(encrypted);

print(decrypted); // Lorem ipsum dolor sit amet, consectetur adipiscing elit print(encrypted.base64); // random cipher text print(fernet.extractTimestamp(encrypted.bytes)); // unix timestamp }

Regards

steinmetz commented 3 years ago

@ramosmarco have you tried if your changes work on web? I get this error when I use it on a web app: Unsupported operation: Uint64 accessor not supported by dart2js

phuchuynhStrong commented 3 years ago

@ramosmarco have you tried if your changes work on web? I get this error when I use it on a web app: Unsupported operation: Uint64 accessor not supported by dart2js

The same for me.

phuchuynhStrong commented 3 years ago

I went deeper into the lib code and found out they use getUint64 and setUint64 when encrypt and decrypt with Fernet. Those functions aren't supported by Dart2Js (https://github.com/dart-lang/sdk/issues/10275) so encryption\decryption with Fernet on Flutter Web is still not available.

FreeXeeD commented 3 years ago

First, i want you to put in context. I already had an app that was using this library on version 4.0.2. This app already stored encrypted messages on a database. Today i updated to version 5.0.0 and i get this error.

This is the code was using to encrypt/decrypt: static final key = Key.fromUtf8('My32LengthPass'); static final b64key = Key.fromUtf8(base64Url.encode(key.bytes)); static final _encrypter = Encrypter(Fernet(b64key));

static String encode(String data) { try { return _encrypter.encrypt(data).base64; } catch(Exception) { return ""; } }

static String decode(String data) { try { return _encrypter.decrypt64(data).toString(); } catch(Exception) { return ""; } }

To solve this issue, i removed the b64key and used key directly:

static final key = Key.fromUtf8('My32LengthPass');

static final _encrypter = Encrypter(Fernet(key));

Hope it works for you too. Sorry for my english :D

fuadarradhi commented 3 years ago

thanks @FreeXeeD for sharing, that working in lastest release

kiloki-official commented 3 years ago

@ramosmarco, your example worked for me. Thanks. I don't understand why the example on the package's page didn't. They should update it.

theshahzaibc commented 2 years ago

Use this code:

import 'package:encrypt/encrypt.dart';

void main() {
  final plainText = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit';

  final key = Key.fromSecureRandom(32);
  final iv = IV.fromSecureRandom(16);
  final encrypter = Encrypter(AES(key));

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

  print(decrypted);
  print(encrypted.bytes);
  print(encrypted.base16);
  print(encrypted.base64);
}

I hope your problem is solved! If yes enjoy and pray for me. Thank you.

Tyroneexe commented 1 year ago

after upgrade to v4.1.0, always return error "Fernet key must be 32 url-safe base64-encoded bytes."

but tested with 4.0.1 and 4.0.2 work fine...

What version are you talking about, The Fernet version, The programming software version?????? I'm also having this problem, how do you go to the older version of whatever you are talking about??

fuadarradhi commented 1 year ago

after upgrade to v4.1.0, always return error "Fernet key must be 32 url-safe base64-encoded bytes." but tested with 4.0.1 and 4.0.2 work fine...

What version are you talking about, The Fernet version, The programming software version?????? I'm also having this problem, how do you go to the older version of whatever you are talking about??

no need to downgrade, just use code in comment

pauloantonelli commented 1 year ago

still same problem in 5.0.1 on IOS!

any solution?

demo-Ashif commented 10 months ago

I have solved this by doing in this way (consider I have a a client secret and secret message getting from server which is base64 encoded)

class EncryptionUtil {
  static String decrypt(String secretMessage, String secretKey) {
    final fernet = Fernet(Key.fromBase64(secretKey));
    final encrypter = Encrypter(fernet);
    return encrypter.decrypt(Encrypted.fromBase64(secretMessage));
  }
}