1

I am trying to implement encryption in Flutter, I'm using java as a backend and dart for the mobile application. I have taken code from this Encryption in Java and Decryption in Flutter (AES-256) But it only supplies decryption in Flutter, and I want to implement encryption in Flutter so the Java code can decrypt it.

Can you help me by providing the code for encryption in Flutter?

This is the java code for encryption and decryption.

public class EncryptionService {
    public String encrypt(String item) throws Exception {
        byte[] ivBytes;
        String password = "Hello";
        /* you can give whatever you want for password. This is for testing purpose */
        SecureRandom random = new SecureRandom();
        byte bytes[] = new byte[20];
        random.nextBytes(bytes);
        byte[] saltBytes = bytes;
        // Derive the key
        SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");

        PBEKeySpec spec = new PBEKeySpec(password.toCharArray(), saltBytes, 65556, 256);

        SecretKey secretKey = factory.generateSecret(spec);
        SecretKeySpec secret = new SecretKeySpec(secretKey.getEncoded(), "AES");

        System.out.println("saltBytes : " + saltBytes);

        // encrypting the word
        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
        cipher.init(Cipher.ENCRYPT_MODE, secret);
        AlgorithmParameters params = cipher.getParameters();
        ivBytes = params.getParameterSpec(IvParameterSpec.class).getIV();
        System.out.println("ivBytes : " + ivBytes);

        byte[] encryptedTextBytes = cipher.doFinal(item.getBytes("UTF-8"));
        // prepend salt and vi
        byte[] buffer = new byte[saltBytes.length + ivBytes.length + encryptedTextBytes.length];
        System.arraycopy(saltBytes, 0, buffer, 0, saltBytes.length);
        System.arraycopy(ivBytes, 0, buffer, saltBytes.length, ivBytes.length);
        System.arraycopy(encryptedTextBytes, 0, buffer, saltBytes.length + ivBytes.length, encryptedTextBytes.length);
        return new Base64().encodeToString(buffer);
    }

    public String decrypt(String encryptedText) throws Exception {
        String password = "Hello";
        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
        // strip off the salt and iv
        ByteBuffer buffer = ByteBuffer.wrap(new Base64().decode(encryptedText));
        byte[] saltBytes = new byte[20];
        buffer.get(saltBytes, 0, saltBytes.length);
        byte[] ivBytes1 = new byte[cipher.getBlockSize()];
        buffer.get(ivBytes1, 0, ivBytes1.length);
        byte[] encryptedTextBytes = new byte[buffer.capacity() - saltBytes.length - ivBytes1.length];

        buffer.get(encryptedTextBytes);
        // Deriving the key
        SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
        PBEKeySpec spec = new PBEKeySpec(password.toCharArray(), saltBytes, 65556, 256);
        SecretKey secretKey = factory.generateSecret(spec);
        SecretKeySpec secret = new SecretKeySpec(secretKey.getEncoded(), "AES");
        cipher.init(Cipher.DECRYPT_MODE, secret, new IvParameterSpec(ivBytes1));
        byte[] decryptedTextBytes = null;
        try {
            decryptedTextBytes = cipher.doFinal(encryptedTextBytes);
        } catch (IllegalBlockSizeException e) {
            e.printStackTrace();
        } catch (BadPaddingException e) {
            e.printStackTrace();
        }

        return new String(decryptedTextBytes);
    }
}

Dart implementation for decryption is something like this

class EncryptionHelper {
  static String decrypt(
    String ciphertext,
  ) {
    Uint8List ciphertextlist = base64.decode(ciphertext);
    var salt = ciphertextlist.sublist(0, 20);
    var iv = ciphertextlist.sublist(20, 20 + 16);
    var encrypted = ciphertextlist.sublist(20 + 16);

    Uint8List key = generateKey("Hello", salt);
    CBCBlockCipher cipher = new CBCBlockCipher(new AESFastEngine());

    ParametersWithIV<KeyParameter> params =
        new ParametersWithIV<KeyParameter>(new KeyParameter(key), iv);

    PaddedBlockCipherParameters<ParametersWithIV<KeyParameter>, Null>
        paddingParams =
        new PaddedBlockCipherParameters<ParametersWithIV<KeyParameter>, Null>(
            params, null);
    PaddedBlockCipherImpl paddingCipher =
        new PaddedBlockCipherImpl(new PKCS7Padding(), cipher);
    paddingCipher.init(false, paddingParams);
    var val = paddingCipher.process(encrypted);

    return new String.fromCharCodes(val);
  }

  static Uint8List generateKey(String passphrase, Uint8List salt) {
    Uint8List passphraseInt8List = Uint8List.fromList(passphrase.codeUnits);

    KeyDerivator derivator =
        PBKDF2KeyDerivator(HMac(SHA1Digest(), 64)); // 64 byte block size
    Pbkdf2Parameters params =
        Pbkdf2Parameters(salt, 65556, 32); // 32 byte key size
    derivator.init(params);
    return derivator.process(passphraseInt8List);
  }
}
Richard Heap
  • 48,344
  • 9
  • 130
  • 112
yong ho
  • 3,892
  • 9
  • 40
  • 81
  • 1
    Since this is about encryption with Flutter, you should post your most recent Flutter code for *encryption*. Currently you have only posted the code for decryption. – Topaco Jun 13 '22 at 13:40
  • @Topaco I don't know how to write the code for encryption. I merely copied the code online. – yong ho Jun 13 '22 at 14:50
  • Wouldn't you 'reverse' the decryption? Derive the key the same way, flip false to true in `paddingCipher.init()` then assemble the salt, iv and ct in order (consider using `BytesBuilder`), finally base64 encoding the result. Having the Java code to copy helps you, as you can check the intermediate results as you perform the steps. (Of course you need to stick with a fixed salt.) – Richard Heap Jun 13 '22 at 15:24
  • As a starting point for troubleshooting, please post an initial version of the encryption code using the posted decryption code and/or PointyCastle examples. – Topaco Jun 13 '22 at 17:31

1 Answers1

0

Why don't you use pointcastle ? it is a dart porting of Bouncy castle and, as I can read in their page, there is yet the implementation of the AES algorithm for decrypt/encrpyt.

Moreover use :

https://pub.dev/packages/encrypt

that is a convenient wrapper on top of pointcastle.

Mike
  • 335
  • 1
  • 8