I have a server code (Java) which encrypts a string using the below method:
public static String encrypt(String plainText, String key) throws Exception {
byte[] rawKey = key.getBytes(StandardCharsets.UTF_8);
System.out.println("key size " + rawKey.length + " key: " + key);
SecretKeySpec secretKey = new SecretKeySpec(rawKey, "AES");
// Generate a random IV
byte[] iv = new byte[12];
new SecureRandom().nextBytes(iv);
Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
cipher.init(Cipher.ENCRYPT_MODE, secretKey, new GCMParameterSpec(128, iv));
byte[] encryptedBytes = cipher.doFinal(plainText.getBytes(StandardCharsets.UTF_8));
// Combine IV and ciphertext for transmission
byte[] cipherTextWithIv = new byte[iv.length + encryptedBytes.length];
System.arraycopy(iv, 0, cipherTextWithIv, 0, iv.length);
System.arraycopy(encryptedBytes, 0, cipherTextWithIv, iv.length, encryptedBytes.length);
return Base64.getEncoder().encodeToString(cipherTextWithIv);
}
//Base64 encoded output:
String encrypt = Test.encrypt("I am new to flutter", "mythirtytwolengthlonguniquekey12");
Output: zuaKIqlEBJKVMsqvBb4hfhONkxL9xVyJdezcnS/SSPRswF3P8VfPOJRBKtpvrEs=
Now when I use this output on dart side and try to decrypt it, it prints some gibberish characters.
//dart decrypt logic using 'encrypt: ^5.0.3':
void main() {
final encryptedBase64 = "zuaKIqlEBJKVMsqvBb4hfhONkxL9xVyJdezcnS/SSPRswF3P8VfPOJRBKtpvrEs=";
String uniqueKey = 'mythirtytwolengthlonguniquekey12';
// Extract IV (first 12 bytes)
var ivLength = 12;
final iv = IV.fromBase64(encryptedBase64.substring(0, ivLength));
// Extract ciphertext (remaining bytes)
final cipherText = Encrypted.fromBase64(encryptedBase64.substring(ivLength));
var key = Key.fromUtf8(uniqueKey);
final encrypter = Encrypter(AES(key, mode: AESMode.gcm, padding: null));
final decrypted = encrypter.decrypt(
cipherText,
iv: iv,
);
print(decrypted);
}
Output: �qۉ_t�������'�����Ϧ�<��8}'&�e
The secret key and IV are correct. Padding is set to null. Also I am extracting the IV from the base64 text and decrypting only the cipher text.
What wrong am I doing?
Updated the decryption logic based on the suggestion from goose:
void main() {
final encryptedBase64 = "zuaKIqlEBJKVMsqvBb4hfhONkxL9xVyJdezcnS/SSPRswF3P8VfPOJRBKtpvrEs=";
var decodedString = base64Decode(encryptedBase64);
String uniqueKey = 'mythirtytwolengthlonguniquekey12';
// Extract IV (first 12 bytes)
var ivLength = 12;
final iv = decodedString.sublist(0, ivLength);
// Extract ciphertext (remaining bytes)
// final cipherText = Encrypted.decodedString.substring(ivLength);
final cipherText = decodedString.sublist(12);
var key = Key.fromUtf8(uniqueKey);
final encrypter = Encrypter(AES(key, mode: AESMode.gcm));
final decrypted = encrypter.decrypt(
Encrypted.fromBase64(base64.encode(cipherText)),
iv: IV.fromBase64(base64.encode(iv)),
);
print(decrypted);
}