0

I have an app that writes data to a file line by line. Once finished, the data needs to be zipped and transmitted to a server. I want to make sure that after zipping but before transmitting the data to the server, the data is secure. Thus, I want to encrypt the zip (or the contents). Moreover, I want to use asymmetric encryption because the source code will be viewed by others.

Is there any way to do this in flutter/dart?

My alternative solution would be to read the data back into the app, encrypt it, write it again, and then zip it. What are your thoughts?

koenniem
  • 506
  • 2
  • 10
  • 1
    With an _asymmetric_ encryption, such as RSA, only data of limited length can be encrypted. The maximum length corresponds to the key length, i.e. for a 2048 bits key a maximum of 256 bytes. For longer data, _symmetric_ encryption (e.g. AES) must be used, or a combination (hybrid encryption) if the symmetric key is to be encrypted with an asymmetric method, e.g. to send it to other parties. During encryption, _binary_ data is processed and _binary_ data is returned. The zipping can therefore in principle take place before or after the encryption depending on the requirement. – Topaco Dec 18 '20 at 12:37
  • So the way I understand it, it's not possible to encrypt entire files with asymmetric encryption? What is your recommendation for keeping the data secure before sending it to the server? – koenniem Dec 18 '20 at 12:50
  • 1
    Concerning Q1: It's not possible if the data volume is too large (at the latest if it's larger than the key size), concerning Q2: Encryption with an symmetric encryption (e.g. AES) or an hybrid encryption (s. above). Maybe HTTPS is an option for you, [here](https://stackoverflow.com/q/49839729/9014097). – Topaco Dec 18 '20 at 13:16

1 Answers1

2

As @Topaco accurately stated, asymmetric encryption of a large file comes with important performance drawbacks.

It can be achieved by splitting the file into smaller chunks of data and encrypting each part. But again, this is not recommended.

That said, you encrypt/decrypt a String with RSA using the rsa_encrypt package for Flutter:

import 'package:rsa_encrypt/rsa_encrypt.dart';
import 'package:pointycastle/api.dart' as crypto;

//Future to hold our KeyPair
Future<crypto.AsymmetricKeyPair> futureKeyPair;

//to store the KeyPair once we get data from our future
crypto.AsymmetricKeyPair keyPair;

Future<crypto.AsymmetricKeyPair<crypto.PublicKey, crypto.PrivateKey>> getKeyPair()
{
var helper = RsaKeyHelper();
return helper.computeRSAKeyPair(helper.getSecureRandom());
}

/*
- Generate KeyPair with the function getKeyPair() store the returned value in futureKeyPair.

- Once we get data from the future we can store that data in keyPair (Now we have acces to our private and public key).

- In order to view our keys as "a string" we need to use two functions encodePrivateKeyToPemPKCS1(keyPair.privateKey) & encodePublicKeyToPemPKCS1(keyPair.publicKey).

- In order to encrypt and decrypt strings you can use two functions

- encrypt() : use this function to encrypt a string, pass your string as first argument and a public key as the second one. [IMPORTANT]: this will return a string so you should store the returned value in a variable.

- decrypt() : use this function to decrypt an encrypted String, pass your encrypted String as first argument and a private key as the second. this will also return a string dont forget to store it :)
*/

A solution to encrypt a file would be to use a safe symmetric encryption algorithm with a random secret key, which is then encrypted with an asymmetric algorithm. This approach is commonly referred to as hybrid cryptosystem.

Stefano Amorelli
  • 4,553
  • 3
  • 14
  • 30