Search code examples
flutterdartencryption

Can't decrypt data flutter


I want to add auto sign in functions to my app. Also it should include encrypt/decrypt function.

My code is below:

this is where I get the parameters and encrypt them. I updated it as below



import 'package:encrypt/encrypt.dart';

class EncryptData {
static Encrypted? encrypted;
static var decrypted;
static final iv = IV.fromLength(16);


static encryptAES(String plainText, String userKey) {
print(plainText);
final key = Key.fromUtf8(userKey);
// final iv = IV.fromLength(16);
final encrypter = Encrypter(AES(key));
encrypted = encrypter.encrypt(plainText, iv: iv);
print(encrypted!.base64);
return encrypted;
 }

 static decryptAES(String encrypted, String userKey, String ivBase64) {
 final key = Key.fromUtf8(userKey);
 final iv = IV.fromBase64(ivBase64); //creating iv from the ivBase64 string
final encrypter = Encrypter(AES(key));
decrypted = encrypter.decrypt64(encrypted, iv: iv);
return decrypted.toString();
 }
}

I tried to add iv in storage:

 final storage =  FlutterSecureStorage();
                    SharedPreferences pref = await SharedPreferences.getInstance();
                     final userId = _auth.currentUser!.uid;
                     final newDateString = "1kr95ye3mcfgjt124p-54";  
                    String subUserId = userId.substring(0, 11);  
                    String key = subUserId + newDateString;
                    final String ivToBase64 = EncryptData.iv.base64 //store this in local storage
                    final String ivFromBase64 = IV.fromBase64(ivToBase64).base64;
                    var encryptMail;
                    var encryotPassword;
                    var encryptMailD;
                    var encryotPasswordD;
                    print("ANAHTAR: "+ key);
                    encryptMail = EncryptData.encryptAES(email.toString(), key);
                    encryotPassword = EncryptData.encryptAES(sifre.toString(), key); 
                    encryptMailD = EncryptData.decryptAES(encryptMail.base64, key,ivFromBase64);
                    encryotPasswordD = EncryptData.decryptAES(encryotPassword.base64, key,ivFromBase64);
                    print("DENEME : " + email);
                    print("DENEME : " + sifre);
                    print("DENEME2 : " + encryptMail.base64);
                    print("DENEME2 : " + encryotPassword.base64);
                    print("DENEME3 : " + encryptMailD.toString());
                    print("DENEME3 : " + encryotPasswordD.toString());
                    await storage.write(key: 'mail2', value: encryptMail!.base64);
                    await storage.write(key: 'password2', value: encryotPassword!.base64);
                    await storage.write(key: 'loginState2', value: true.toString());
                    await storage.write(key: "ilkOturum", value: "false");
                    await storage.write(key: "iv2", value: ivToBase64);
                    pref.setString('mail', encryptMail.base64);
                    pref.setString('password', encryotPassword.base64);
                    pref.setString('iv', ivToBase64);
                    pref.setBool('loginState', true);
                    print("bilgiler kayıt edildi");

and then decrypt :

var mail = await storage.read(key: 'mail2');
var password = await storage.read(key: 'password2');
var iv = await storage.read(key: 'iv2');

          if (mail != null && password != null) {
  var encryptMailD = EncryptData.decryptAES(mail, key, iv.toString());
  var encryotPasswordD = EncryptData.decryptAES(password, key, iv.toString());

Now it is working! Thanks for your help


Solution

  • Inside the encryptAES method and decryptAES the initialization vector (IV) is being generated independently, leading to an "Invalid or corrupted pad lock" error during decryption. When decrypting the "iv" should same which is used for encrypting the string.

    Furthermore, it's important to note that when using IV.fromLength(16), it internally relies on Random.secure(), resulting in a different IV each time. To maintain consistency, consider storing and utilizing the same IV for both encryption and decryption, thereby preventing decryption errors.

    class EncryptData {
    static Encrypted? encrypted;
    static var decrypted;
    
    static final iv = IV.fromLength(16);
    
    static encryptAES(String plainText, String userKey) {
    print(plainText);
    final key = Key.fromUtf8(userKey);
    // final iv = IV.fromLength(16);
    final encrypter = Encrypter(AES(key));
    encrypted = encrypter.encrypt(plainText, iv: iv);
    print(encrypted!.base64);
    return encrypted;
     }
    
     static decryptAES(String encrypted, String userKey, String 
        ivBase64) {
     final key = Key.fromUtf8(userKey);
     final iv = IV.fromBase64(ivBase64); //creating iv from the ivBase64 string
    final encrypter = Encrypter(AES(key));
    decrypted = encrypter.decrypt64(encrypted, iv: iv);
    return decrypted.toString();
     }
    }
    

    final String ivToBase64 = iv.base64; //store this in local storage
    
    final String ivFromBase64 = IV.fromBase64(ivToBase64);