Trang web để kiểm tra tính chính xác của AES
https://www.toolhelper.cn/SymmetricEncryption/AES
Mã nguồn Java backend như sau:
<pre><code>
public static String encodeText(String plain, String keyStr, String initVector) {
byte[] result = null;
try {
byte[] secretKeyBytes = convertToByte(doubleMD5(keyStr));
result = encryptData(plain.getBytes(), secretKeyBytes, initVector);
} catch (Exception e) {
e.printStackTrace();
}
return bytesToHex(result);
}
private static byte[] encryptData(byte[] plaintext, byte[] secretKey, String iv) throws Exception {
SecretKeySpec spec = new SecretKeySpec(secretKey, "AES");
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, spec, new IvParameterSpec(iv.getBytes()));
byte[] encrypted = cipher.doFinal(plaintext);
return encrypted;
}
public static byte[] convertToByte(String hexString) {
int length = hexString.length() / 2;
byte[] output = new byte[length];
for (int i = 0; i < length; i++) {
output[i] = (byte) ((Character.digit(hexString.charAt(2 * i), 16) << 4)
+ Character.digit(hexString.charAt(2 * i + 1), 16));
}
return output;
}
private static String bytesToHex(byte[] byteArray) {
if (byteArray == null) return "";
StringBuilder hexResult = new StringBuilder(2 * byteArray.length);
for (byte b : byteArray) {
hexResult.append(String.format("%02x", b));
}
return hexResult.toString();
}
</code></pre>
Ví dụ kiểm thử:
<pre><code>
plainText = test123456 key = 1691645969 iv = a0fe7c7c98e09e8c Kết quả mã hóa AES: 30f3084aae678924002f6f0c41e77784
</code></pre>
Mã hóa văn bản test123456, java backend sử dụng key là timestamp 1691645969, MD5 hai lần và sau đó thực hiện AES. IV cho AES là a0fe7c7c98e09e8c.
Lưu ý rằng trên Java backend dùng AES/CBC/PKCS5Padding, PKCS5 và PKCS7 giống nhau. Khi kiểm thử trên các nền tảng khác có thể sử dụng PKCS7.
Flutter sử dụng thư viện bên thứ ba:
<pre><code>
encrypt: ^5.0.1 #AES
crypto: ^3.0.3 #MD5
</code></pre>
Nhập các header file:
<pre><code>
import 'package:encrypt/encrypt.dart' as enc;
import 'package:crypto/crypto.dart';
</code></pre>
Mã nguồn:
<pre><code>
DateTime now = DateTime.now();
int timestamp = now.millisecondsSinceEpoch;
print('Timestamp hiện tại: $timestamp');
var nonce = '$timestamp';
nonce = '1691645969';
print('Nonce: $nonce');
var secretKey = doubleMD5(nonce);
print('Secret Key: $secretKey');
var encryptedText = aesEncrypt('test123456', secretKey, 'a0fe7c7c98e09e8c');
print(encryptedText);
</code></pre>
Ban đầu key và iv đều được sử dụng từUtf8, kết quả không khớp với backend. May mắn thay, trang web kiểm thử giúp kiểm tra từng kết quả.
<pre><code>
String aesEncrypt(String text, String secretKey, String ivString) {
final key = enc.Key.fromBase16(secretKey);
final iv = enc.IV.fromUtf8(ivString);
final encrypter = enc.Encrypter(enc.AES(key, mode: enc.AESMode.cbc));
final encrypted = encrypter.encrypt(text, iv: iv);
return encrypted.base16.toLowerCase();
}
</code></pre>