AES Encryption(Intro).Comparing AES encryption in Dart and Java with an example.
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…!!!