AES Encryption(Intro).Comparing AES encryption in Dart and Java with an example.

Ganesh L G
3 min readDec 25, 2020

--

The following article gives you a small idea about AES (Advanced encryption standard).

The advanced encryption standard is a symmetric block cipher. AES is implemented in software and hardware all over the world to encrypt data.

Now let us see how does it work,

AES includes three block ciphers :

AES-128

AES-192

AES-256

As the name only defines that AES-128,192,256 uses 128,192,256 bit key length to encrypt and decrypt a block of messages. Each cipher encrypts and decrypts data in blocks of 128 bits using cyptographic keys of 128,192 and 256 bits respectively.

The ciphers use the same key for encrypting and decrypting, so the sender and receiver must both know and use same secret key.

Described above types uses different rounds in the process. A round consists of several processing steps that include substitution, transportation and mixing of the input plain text to transform it into the final output of cipher text.

128 bit keys -> 10 rounds

192 bit keys -> 12 rounds

256 bit keys -> 14 rounds

Below, you can see the basic design diagram for reference…!!!

Let’s understand what is IV(initialization vector) before proceeding to the example.

IV(initialization vector) -> In cryptography an initialization vector is a fixed size input to a cryptographic primitive.

In simple words, IV adds randomness to the start of your encryption process.

Below you can find example for AES encryption in both java(Native) and dart(Flutter).

Java-AESHelper.java

import android.os.Build;

import android.util.Base64;

import androidx.annotation.RequiresApi;

import java.nio.charset.StandardCharsets;

import java.util.Arrays;

import javax.crypto.Cipher;

import javax.crypto.spec.IvParameterSpec;

import javax.crypto.spec.SecretKeySpec;

public class AesHelper {

private static final String keyMain = “aesEncryptionKey”;

private static final String initVector = “aesEncryptionIV!”;

@RequiresApi(api = Build.VERSION_CODES.KITKAT)

public static String encrypt(String value) {

try {

IvParameterSpec iv = new IvParameterSpec(initVector.getBytes(“UTF-8”));

SecretKeySpec skeySpec = new SecretKeySpec(keyMain.getBytes(“UTF-8”), “AES”);

System.out.println(“Native Output…!!!”);

System.out.println(“IV: “+Arrays.toString(iv.getIV()));

System.out.println(“KEY: “+Arrays.toString(skeySpec.getEncoded()));

Cipher cipher = Cipher.getInstance(“AES/CBC/PKCS7PADDING”);

cipher.init(Cipher.ENCRYPT_MODE, skeySpec, iv);

byte[] encrypted = cipher.doFinal(value.getBytes());

System.out.println(“Encrypted: “+Arrays.toString(encrypted));

System.out.println(“Base64: “+Base64.encodeToString(encrypted,0));

return Base64.encodeToString(encrypted,0);

} catch (Exception ex) {

ex.printStackTrace();

}

return null;

}

@RequiresApi(api = Build.VERSION_CODES.KITKAT)

public static String decrypt(String encrypted) {

try {

IvParameterSpec iv = new IvParameterSpec(initVector.getBytes(“UTF-8”));

SecretKeySpec skeySpec = new SecretKeySpec(keyMain.getBytes(“UTF-8”), “AES”);

Cipher cipher = Cipher.getInstance(“AES/CBC/PKCS5PADDING”);

cipher.init(Cipher.DECRYPT_MODE, skeySpec, iv);

byte[] original = cipher.doFinal(Base64.decode(encrypted,0));

System.out.println(new String(original));

return new String(original);

} catch (Exception ex) {

ex.printStackTrace();

}

return null;

}

}

Dart-AESHelper.dart

import ‘package:encrypt/encrypt.dart’;//pubspec.yaml->encrypt: ^4.1.0

String key = “aesEncryptionKey”;

String iv = “aesEncryptionIV!”;

Encrypted encrypt(String plainText){

final key1 = Key.fromUtf8(key);

final iv1 = IV.fromUtf8(iv);

final encrypter = Encrypter(AES(key1));

print(“Dart Output…!!!”);

print(“IV: “ + iv1.bytes.toString());

print(“Key: “ + key1.bytes.toString());

final encrypted = encrypter.encrypt(plainText, iv: iv1);

print(“Encrypted: “+ encrypted.bytes.toString());

print(“Base64: “+encrypted.base64);

return encrypted;

}

String decrypt(Encrypted encrypted){

final key1 = Key.fromUtf8(key);

final iv1 = IV.fromUtf8(iv);

final encrypter = Encrypter(AES(key1));

final decrypted = encrypter.decrypt(encrypted, iv: iv1);

print(“Decrypted: “+ decrypted);

return decrypted;

}

Comparing AES encryption in Java and Dart.

Native Output…!!!

IV: [97, 101, 115, 69, 110, 99, 114, 121, 112, 116, 105, 111, 110, 73, 86, 33]

KEY: [97, 101, 115, 69, 110, 99, 114, 121, 112, 116, 105, 111, 110, 75, 101, 121]

Encrypted: [-83, 37, -81, -115, -48, 49, -15, -97, -54, -96, 54, -101, 109, 34, 95, -121]

Base64: rSWvjdAx8Z/KoDabbSJfhw==

Decrypted: Ganesh L G

Dart Output…!!!

IV: [97, 101, 115, 69, 110, 99, 114, 121, 112, 116, 105, 111, 110, 73, 86, 33]

Key: [97, 101, 115, 69, 110, 99, 114, 121, 112, 116, 105, 111, 110, 75, 101, 121]

Encrypted: [173, 37, 175, 141, 208, 49, 241, 159, 202, 160, 54, 155, 109, 34, 95, 135]

Base64: rSWvjdAx8Z/KoDabbSJfhw==

Decrypted: Ganesh L G

The negative numbers in encrypted byte array in native side is due to java signed byte’s(range:-128 to 127), but dart is using unsigned byte’s(range:-0 to 255).

(just add +256 to negative byte’s to cross verify).

Thank You…!!!

--

--

Ganesh L G

Software Engineer(Flutter,Native Android — Mobile Application Developer)