How to fill the required parameters for cipher.doFinal() method in Dart?

307

In case anyone has encountered this case. This is what I ended up with:

import 'package:pointycastle/export.dart';

class Example {
  Uint8List encrypt(String data) {
    if (data == null || data.length == 0) return null;
    final Uint8List _key = utf8.encode('key');
    final Uint8List _iv = utf8.encode('iv');
    try {
      Uint8List encrypted;
      final CipherParameters params = PaddedBlockCipherParameters(
        ParametersWithIV(
          KeyParameter(_key),
          _iv,
        ),
        null,
      );
      final PaddedBlockCipherImpl cipher = PaddedBlockCipherImpl(
        PKCS7Padding(),
        CBCBlockCipher(
          AESFastEngine(),
        ),
      );
      cipher.init(true, params);
      encrypted = cipher.process(utf8.encode(data));
      return encrypted;
    } catch (_) {
      print(_);
      return null;
    }
  }

  String decrypt(Uint8List data) {
    if (data == null || data.length == 0) return null;
    final Uint8List _key = utf8.encode('key');
    final Uint8List _iv = utf8.encode('iv');
    try {
      final CipherParameters params = PaddedBlockCipherParameters(
        ParametersWithIV(
          KeyParameter(_key),
          _iv,
        ),
        null,
      );
      final PaddedBlockCipherImpl cipher = PaddedBlockCipherImpl(
        PKCS7Padding(),
        CBCBlockCipher(
          AESFastEngine(),
        ),
      );
      cipher.init(false, params);
      final String finalData = utf8.decode(cipher.process(data));
      return finalData;
    } catch (_) {
      print(_);
      return null;
    }
  }
}

Thanks to https://stackoverflow.com/users/9014097/topaco and https://github.com/Nguyenpk57 for the inspiration.

Share:
307
Omar Hussein
Author by

Omar Hussein

Updated on December 11, 2022

Comments

  • Omar Hussein
    Omar Hussein over 1 year

    I'm trying to do encryption in my Flutter application using pointy_castle package, which is similar to crypto.Cipher library in Java. There is a method called doFinal(), in Java, you can assign one parameter. While in Dart, you have to assign four parameters. So how can I properly fill the required parameters? I need an example of how to do this.

    In the package docs, doFinal(Uint8List inp, int inpOff, Uint8List out, int outOff) → int

    This is the code in Java:

     ...
        byte[] encrypted;
        encrypted = cipher.doFinal(padString(text).getBytes());
        String finalData = bytesToHex(encrypted);
        return finalData;
     ...
    

    And in Dart:

    ...
        Uint8List encrypted; // <- I have to make it of type Uint8List because _bytesToHex method requires looping through the list. However, it produces an error because of that: `A value of type 'int' can't be assigned to a variable of type 'Uint8List'.`
        encrypted = cipher.doFinal(utf8.encode(_padString(data))); // <- This produces an error since doFinal() requires 4 params.
        String finalData = _bytesToHex(encrypted);
        return finalData;
    ...
    
    • President James K. Polk
      President James K. Polk almost 5 years
      The description in the docs seems quite clear and complete. What part don't you understand?
    • Omar Hussein
      Omar Hussein almost 5 years
      How should I properly fill the parameters in my case?
    • Michael
      Michael almost 5 years
      It's still not clear what in the documentation that you found lacking. Given that you want to encrypt all of the data in the input list and write the result to the start of the output list - what would reasonable values be for each of the parameters?
    • Omar Hussein
      Omar Hussein almost 5 years
      @Michael I tried to accomplish what you explained, but unfortunately, I had no luck with it, may you please be more specific?
    • Topaco
      Topaco almost 5 years
      The parameters are explained in the documentation of doFinal, see here. Also note, that it is better to use process (see description of PaddedBlockCipher in the same place). An example (AES-CBC, PKCS7-padding) can be found here. An example of the use of doFinal can be found within the body of process, see here.