Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Zip encryption not implemented #141

Open
koenniem opened this issue Dec 16, 2020 · 4 comments
Open

Zip encryption not implemented #141

koenniem opened this issue Dec 16, 2020 · 4 comments
Milestone

Comments

@koenniem
Copy link

As the title says, encryption for zip files was never implemented. I'm not sure if this is intentional or not.

The way I see it, there is no method to set a simple password for the zip (though this is a weaker method in general). My suggestion is to encrypt the JSON file in its entirety and then zip it. However, I'm not sure how this interacts with sink.

@bardram
Copy link
Contributor

bardram commented Dec 17, 2020

I need good input on how to do this. What would be the best approach in Flutter to implement a PKI setup?

@koenniem
Copy link
Author

From my SO question:

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.

There indeed seems to be a limit in the size of the data when using asymmetric encryption I was not aware of (see here and here). I'm not sure if this implies the ZIP itself (or rather the file) cannot be encrypted (unless it's symmetrically done). If so, you can either encrypt every line individually (although I'm not sure how that impacts performance) or by using a hybrid approach, i.e. generating a symmetric key to encrypt the file and then encrypt that key with a public key.

The hybrid approach seems a bit nicer although it requires an extra key to be sent. On the other hand, encrypting line by line is easy to implement in the current set-up. What are your thought on this?

@koenniem
Copy link
Author

I think a hybrid approach could be achieved by using the encrypt package. In flush() in file_data_manager.dart:

/// Flushes data to the file, compress, encrypt, and close it.
void flush(File flushFile, IOSink flushSink) {

 (...)

  // once finished closing the file, then zip and encrypt it
  // Actually, it should be the other way around then
  flushSink.close().then((value) {
    // encrypt the zip file
    if (_fileDataEndPoint.encrypt) {
      // Create a new symmetric key (32 bytes)
      final key = Key.fromLength(32);
      final iv = IV.fromLength(16);

      // TODO: Read in file, encrypt, and save.
      final AESEncrypter = Encrypter(AES(key));
      final encrypted = AESEncrypter(file, iv: iv);

      // Convert public key to PEM and then to RSAPublicKey
      // Assumes [_fileDataEndPoint.publicKey] is a base64 RSA key without headers
      String pk = _fileDataEndPoint.publicKey;
      String pem = '-----BEGIN RSA PUBLIC KEY-----\n$pk'
         '\n-----END RSA PUBLIC KEY-----';
      final pubkey = RSAKeyParser().parse(pem);

      // Encrypt symmetric key with public key
      final RSAEncrypter = Encrypter(RSA(publicKey: pubkey, privateKey: null)); // Not sure if it can be null
      final encryptedKey = RSAEncrypter.encrypt(key); // Save it to somewhere

      addEvent(FileDataManagerEvent(
            FileDataManagerEventTypes.FILE_ENCRYPTED, _finalFilePath));
    }
    if (_fileDataEndPoint.zip) {
      (...)
    }
  });
}

Unfortunately, I don't know enough about dart to implement the reading and writing of the file. Nevertheless, I think this shows the general idea. As long as there aren't too many zips (i.e. not every second or so), I think it should be okay in terms of computational time and battery.

@bardram
Copy link
Contributor

bardram commented Jan 7, 2021

I think this looks like a sound approach and I will look into how this can be implemented.

@bardram bardram added this to the 0.4.0 milestone Jun 20, 2022
bardram added a commit that referenced this issue Apr 19, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants