is there a Dart Equivalent of the following Aes Encryption function in java

2,146

The way you are configuring the Java cipher defaults to Electronic Code Book (ECB) mode which shouldn't be used in a real cipher system. You are also relying on the default padding - PKCS5.

Use the pointycastle package, with the following imports:

import 'package:pointycastle/api.dart';
import 'package:pointycastle/block/aes_fast.dart';
import 'package:pointycastle/paddings/pkcs7.dart';
import 'package:pointycastle/padded_block_cipher/padded_block_cipher_impl.dart';
import 'package:pointycastle/block/modes/ecb.dart';

An approximate equivalent in Dart is:

List<int> encrypt2(String text) {
  // key must be 16 or 32 bytes - not sure how "mykey" could work
  // key should really be binary, not a String! Better to use a KDF.
  Uint8List key = Uint8List.fromList(
    utf8.encode('0123456789abcdef'),
  );

  PaddedBlockCipher cipher = PaddedBlockCipherImpl(
    PKCS7Padding(), // Java defaults to PKCS5 which is equivalent
    ECBBlockCipher(AESFastEngine()), // Very weak mode - don't use this in the real world
  );

  cipher.init(
    true,
    PaddedBlockCipherParameters<CipherParameters, CipherParameters>(
      KeyParameter(key),
      null,
    ),
  );

  return cipher.process(utf8.encode(text)); // this isn't the same as .toBytes, except for ASCII
}
Share:
2,146
Admin
Author by

Admin

Updated on December 10, 2022

Comments

  • Admin
    Admin over 1 year

    I have set up a server that is listening for an encrypted byte array through the java function mentioned below. Earlier i was using java (android) to build my app so it was easy using the same java function but i am unable to figure out what is the dart equivalent(flutter) of that function which takes a string as input and returns an AES encrypted byte array as output ,which i can write to the tcp socket .

    Also i'd really appreciate help on knowing how to write the generated byte array to the server and then read a similar response and decrypting it through dart (flutter)

    I have been successful in writing simple strings and receiving simple strings as input and output to the tcp server through dart but cant do the same for encrypted byte arrays . In java i used DataOutputStream to send the response to server like this

    DataOutputStream dOut = newDataOutputStream(socket.getOutputStream());
    
               byte[] s2 = Encrypt3.encrypt2(myString);
    
               dOut.writeInt(s2.length); // write length of the message
                dOut.write(s2);
    

    Here is the java function i used for aes encryption

    import java.security.Key;
    
    import javax.crypto.Cipher;
    
    import javax.crypto.spec.SecretKeySpec;
    
    
    public class Encrypt3 {
    public static String key = "mykey";
    
    public static byte[] encrypt2(String text ){
        String encrypt ="";
    
        try{
            // Create key and cipher
            Key aesKey = new SecretKeySpec(key.getBytes(), "AES");
            Cipher cipher = Cipher.getInstance("AES");
            // encrypt the text
            cipher.init(Cipher.ENCRYPT_MODE, aesKey);
            byte[] encrypted = cipher.doFinal(text.getBytes());
            return encrypted ;
        }catch(Exception e){
            System.out.println(e);
        }
        return null ;
    }
    
    
    public static String decrypt2(byte[] encrypted2){
        String decrypt ="";
        try{
            Key aesKey = new SecretKeySpec(key.getBytes(), "AES");
            Cipher cipher = Cipher.getInstance("AES");
            // decrypt the text
            cipher.init(Cipher.DECRYPT_MODE, aesKey);
            decrypt = new String(cipher.doFinal(encrypted2));
        }catch(Exception e){
            System.out.println(e);
        }
    
        return decrypt ;
    }
    
    
    }
    

    I expect the equivalent bytearray to be produced in dart when provided with a string as input,and then writing the byte array to a tcp server.

    Thank You in advance

  • Admin
    Admin about 5 years
    I am new to encryption , i implemented this function in flutter ,and this returned me a List<Int> , i would like to write this list to my server and then decrypt it over there , can i simply do sock.write(encryptedList) to write it to my server ? And can you give me the encrypt and decrypt function for dart and java both Please ? Also do you suggest i use a different padding than pkcs7 ?
  • Richard Heap
    Richard Heap about 5 years
    It's probably sock.add in dart to send it. That dart encrypt should match the existing java decrypt in the question. Pkcs5/7 padding is acceptable for your purposes at the moment. Your main problem comes from using ECB. Read Wikipedia to see why. Decrypt is identical, but change true to false :-)
  • Admin
    Admin about 5 years
    Thanks a lot , i have successfully encrypted the string and decrypted on my server However i am unable to decrypt on the dart side , i received this string through encryption 'Öb9÷Ñ\^] vê~§Ó<…>' which is actually "Text data" . I tried putting false in decrypt but it gives me this error when i pass this string to the decrypt function in dart " Invalid argument(s): Input data length must be a multiple of cipher's block size"
  • Richard Heap
    Richard Heap about 5 years
    Ob9... isn't an array of bytes, so not sure how you would expect to decrypt that. Where are you getting the encrypted data from? Your Java function returns byte[] as you might expect.
  • Admin
    Admin about 5 years
    I am stuck at 1.)the way i am receiving the Stream of bytes from my server . and 2.) the return type of decrypt function , return statement 1.) To receive on dart i am using sock.listen((data) { } I assume data is the byte stream i expect , or should i use stdin for that (please give sample snippet if possible) 2.)my return type of decrypt function is string , it takes a list as an argument(the one we received) , i've changed true to false in cipher.init , now what should be the return statement for this ?
  • Admin
    Admin about 5 years
    I want to first receive the byte array on dart and then decrypt it , but i face the above problems , by mistake i tried to convert the array to string hence the other comment , please ignore that
  • Richard Heap
    Richard Heap about 5 years
    sock.listen should yield bytes, yes. After decrypting the bytes you should get another byte array. Turn this back to characters - closest equiv to java toBytes is utf8.decode(somebytes)
  • Admin
    Admin about 5 years
    for decrypting the recieved byte array , i have to pass it to the decrypt function , what should its argument be , earlier it was string when i was encrypting,now should it be the byte array ?
  • Richard Heap
    Richard Heap about 5 years
    yes and the last line becomes return utf8.decode(cipher.process(cipherText))
  • Bhavin Patel
    Bhavin Patel almost 4 years
    @VaibhavDikha I'm using same Encrypt and decrypt functionality .So,please share class which you created in flutter for encrypt decrypt and api dunction for converting data please