Search code examples
stringflutterencryptionvarfernet

how do i decrypt the encrypted string from firebase


I have successfully encrypted the data and store it in the firebase as a string value, how do i retrieve the string and turn it into var type and allow it to be decrypt ?

import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/material.dart';
import 'package:encrypt/encrypt.dart' as encrypt;
import 'package:hupcarwashcustomer/validation.dart';
import '../../user_model/encrypt_data.dart';
import '../../user_model/payment.dart';

class createPayment extends StatefulWidget {
  final String name;
  createPayment({required this.name});
  @override
  State<createPayment> createState() => _createPaymentState();
}

class _createPaymentState extends State<createPayment> {
  TextEditingController cardNameController = TextEditingController();
  TextEditingController cvvController = TextEditingController();
  TextEditingController cardNumController = TextEditingController();
  TextEditingController expController = TextEditingController();

  void dispose() {
    cardNameController.dispose();
    cvvController.dispose();
    cardNumController.dispose();
    expController.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return SafeArea(
        child: Scaffold(
          appBar: AppBar(title: Text('Payment Form'),),
          body: Padding(
            padding: const EdgeInsets.all(8.0),
            child: ListView(
              children: [
                Text(widget.name.toString()),
                const SizedBox(
                  height: 10,
                ),
                TextFormField(
                  controller: cardNameController,
                  decoration: const InputDecoration(border: OutlineInputBorder(), hintText: "Card Name"),
                ),
                const SizedBox(
                  height: 10,
                ),
                TextFormField(
                  controller: cardNumController,
                  decoration: const InputDecoration(border: OutlineInputBorder(), hintText: "Card Num"),
                ),
                const SizedBox(
                  height: 10,
                ),
                TextFormField(
                  controller: cvvController,
                  decoration: const InputDecoration(border: OutlineInputBorder(), hintText: "CVV"),
                ),
                const SizedBox(
                  height: 10,
                ),
                TextFormField(
                  controller: expController,
                  decoration: const InputDecoration(border: OutlineInputBorder(), hintText: "Exp Month/Year"),
                ),
                const SizedBox(
                  height: 10,
                ),
                ElevatedButton(onPressed: () async {
                  var encryptCardNum, encryptCVV, encryptExp;


                  encryptCardNum = MyEncryptionDecryption.encryptFernet(cardNumController.text);
                  encryptCVV = MyEncryptionDecryption.encryptFernet(cvvController.text);
                  encryptExp = MyEncryptionDecryption.encryptFernet(expController.text);

                  createPayment(payment(cardName: cardNameController.text,
                      cardNum: encryptCardNum.base64, name: widget.name.toString(),
                      cvv: encryptCVV.base64, exp: encryptExp.base64, id:''), widget.name.toString());

                  ScaffoldMessenger.of(context).showSnackBar(const SnackBar(
                      content: Text('Payment details have been successfully saved')));
                  Navigator.pop(context);
                }
                    ,child: const Text('Proceed')),
              ],
            ),
          ),
        )
    );
  }
  Future<void> createPayment(payment pay, String id) async{
    String primarykey = '';
    final userCollection = FirebaseFirestore.instance.collection("Payment").doc();
    primarykey = userCollection.id;
    final newPayment = payment(
      id: primarykey,
        name: pay.name,
        cardName: pay.cardName,
        cardNum: pay.cardNum,
        cvv: pay.cvv,
        exp: pay.exp
    ).toJson();

    try {
      await userCollection.set(newPayment);
    } catch (e) {
      print("some error occured $e");
    }
  }
}



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

class MyEncryptionDecryption {
  // For Fernet Encryption/Decryption
  static final keyFernet = encrypt.Key.fromUtf8('my32lengthsupersecretnooneknows1');
  // if you need to use the ttl feature, you'll need to use APIs in the algorithm itself
  static final fernet = encrypt.Fernet(keyFernet);
  static final encrypterFernet = encrypt.Encrypter(fernet);

  static encryptFernet(text) {
    final encrypted = encrypterFernet.encrypt(text);
    return encrypted;
  }

  static decryptFernet(text) {
    return encrypterFernet.decrypt(text);
  }
}


//this part is to retrieve from firebase string and pass to decryption method
final service = userData[index];
                                final cardNum = service.cardNum;
                                var finalCardNum = MyEncryptionDecryption.decryptFernet(cardNum);


I have shared 2 of my files here, i hope someone can guide me, because if i pass the string value into the decrypt method, i will get error like Encrypt does not accept String value, the image i share is the image of firebase data enter image description here


Solution

  • First change your MyEncryptionDecryption class to this:

    class MyEncryptionDecryption {
      static final keyFernet =
          encrypt.Key.fromUtf8('my32lengthsupersecretnooneknows1');
    
      static final fernet = encrypt.Fernet(keyFernet);
      static final encrypterFernet = encrypt.Encrypter(fernet);
    
      static encrypt.Encrypted encryptFernet(text) {
        final encrypted = encrypterFernet.encrypt(text);
        return encrypted;
      }
    
      static String decryptFernet(encrypt.Encrypted encrypted) {
        return encrypterFernet.decrypt(encrypted);
      }
    }
    

    then for encrypt try this:

    encypted = MyEncryptionDecryption.encryptFernet('hi');
    

    and send encypted!.base64 to your firebase. Then for decrypt try this:

    var result = MyEncryptionDecryption.decryptFernet(encrypt.Encrypted.fromBase64(encoded!));
    
    print("result = $result");// hi
    

    encoded is the string you get from firebase.