coolbeatz71
coolbeatz71

Reputation: 1107

How to Perform File encryption with Flutter and Dart

I need to make a feasibility study for an app I am trying to build. I chose Flutter because it allows me to quickly create mobile apps.

My application will be storing voice messages in the form of audio files. It can be an mp3 or any other audio format.

To make it readable by the receiver only, I need to encrypt the file using maybe AES or e2e encryption.

Is it possible to encrypt files with Dart in my Flutter app?

Upvotes: 13

Views: 16181

Answers (2)

touhid udoy
touhid udoy

Reputation: 4444

I've created a class for ease of use while encryption/decryption.

import 'dart:developer';
import 'dart:io';

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

class CryptoHelper {
  //instead of plain text convert key,iv to base64 and use .fromBase64 for better security

  Future<void> encrypt(
      {required String inputPath,
      required String outputPath,
      required String key,
      required String iv}) async {
    final encryptionKey = encrypt_handle.Key.fromUtf8(key);
    final encryptionIv = encrypt_handle.IV.fromUtf8(iv);
    final encrypter = encrypt_handle.Encrypter(
        encrypt_handle.AES(encryptionKey, mode: encrypt_handle.AESMode.cbc));

    File inputFile = File(inputPath);
    File outputFile = File(outputPath);

    bool outputFileExists = await outputFile.exists();
    bool inputFileExists = await inputFile.exists();

    if (!outputFileExists) {
      await outputFile.create();
    }

    if (!inputFileExists) {
      throw Exception("Input file not found.");
    }

    log('Start loading file');
    final fileContents = await inputFile.readAsBytes();

    log('Start encrypting file');

    final encryptedData = encrypter.encryptBytes(fileContents, iv: encryptionIv);

    log('File Successfully Encrypted!');

    await outputFile.writeAsBytes(encryptedData.bytes);
  }

  Future<void> decrypt(
      {required String inputPath,
      required String outputPath,
      required String key,
      required String iv}) async {
    final encryptionKey = encrypt_handle.Key.fromUtf8(key);
    final encryptionIv = encrypt_handle.IV.fromUtf8(iv);
    final encrypter = encrypt_handle.Encrypter(
        encrypt_handle.AES(encryptionKey, mode: encrypt_handle.AESMode.cbc));

    File inputFile = File(inputPath);
    File outputFile = File(outputPath);

    bool outputFileExists = await outputFile.exists();
    bool inputFileExists = await inputFile.exists();

    if (!outputFileExists) {
      await outputFile.create();
    }

    if (!inputFileExists) {
      throw Exception("Input file not found.");
    }

    log('Start loading file');
    final fileContents = await inputFile.readAsBytes();
    // final decoded = base64.encode(_fileContents);

    log('Start decrypting file');

    final decrypted = encrypter.decryptBytes(encrypt_handle.Encrypted(fileContents), iv: encryptionIv);

    log('File Successfully Decrypted!');

    await outputFile.writeAsBytes(decrypted);
  }
}

I've created this repo for the full source code demo. Tested only on mac, but should work other platforms with minimal effort.

Upvotes: 2

Hosea varghese
Hosea varghese

Reputation: 331

Finally found something. I tried multiple options including the encrypt package, but all were dead ends. I finally found this package It can encrypt files using AES all you need is the path to the file. It is well documented. I believe its best to create a class and add functions for encrypt and decrypt as I have did below.

import 'dart:io';
import 'package:aes_crypt/aes_crypt.dart';

class EncryptData {
  static String encrypt_file(String path) {
    AesCrypt crypt = AesCrypt();
    crypt.setOverwriteMode(AesCryptOwMode.on);
    crypt.setPassword('my cool password');
    String encFilepath;
    try {
      encFilepath = crypt.encryptFileSync(path);
      print('The encryption has been completed successfully.');
      print('Encrypted file: $encFilepath');
    } catch (e) {
      if (e.type == AesCryptExceptionType.destFileExists) {
        print('The encryption has been completed unsuccessfully.');
        print(e.message);
      }
      else{
        return 'ERROR';
      }
    }
    return encFilepath;
  }

  static String decrypt_file(String path) {
    AesCrypt crypt = AesCrypt();
    crypt.setOverwriteMode(AesCryptOwMode.on);
    crypt.setPassword('my cool password');
    String decFilepath;
    try {
      decFilepath = crypt.decryptFileSync(path);
      print('The decryption has been completed successfully.');
      print('Decrypted file 1: $decFilepath');
      print('File content: ' + File(decFilepath).path);
    } catch (e) {
      if (e.type == AesCryptExceptionType.destFileExists) {
        print('The decryption has been completed unsuccessfully.');
        print(e.message);
      }
      else{
        return 'ERROR';
      }
    }
    return decFilepath;
  }
}


Now you can use it like

encrypted_file_path = EncryptData.encrypt_file('your/file/path');

Upvotes: 19

Related Questions