Sebenarnya tidak ada yang salah dengan kueri pertama Anda, secara sintaksis itu tepat seperti yang ditunjukkan oleh contoh yang berhasil ini.
mysql> SET @@SESSION.block_encryption_mode = 'aes-256-cbc';
mysql> create table MyTable(
-> Encrypted_ID varbinary(256),
-> InitializationVector_iv varbinary(16)
-> );
Query OK, 0 rows affected (0.93 sec)
mysql> SET @iv = RANDOM_BYTES(16);
Query OK, 0 rows affected (0.00 sec)
mysql> INSERT INTO MyTable SET Encrypted_ID = AES_ENCRYPT('hello','key', @iv), InitializationVector_iv = @iv;
Query OK, 1 row affected (0.17 sec)
mysql> SELECT CAST(AES_DECRYPT(Encrypted_ID,'key', InitializationVector_iv) AS CHAR) from MyTable;
+------------------------------------------------------------------------+
| CAST(AES_DECRYPT(Encrypted_ID,'key', InitializationVector_iv) AS CHAR) |
+------------------------------------------------------------------------+
| hello |
+------------------------------------------------------------------------+
1 row in set (0.00 sec)
Adapun mengapa itu tidak berfungsi, saya berhasil mendapatkan kueri untuk mengembalikan NULL dalam 2 skenario. Satu, Anda mendapatkan NULL kembali jika Anda menggunakan iv yang berbeda untuk enkripsi dan dekripsi, jadi Anda mungkin ingin melihat bagaimana Anda menyimpan sebagai iv. Dua, Anda mendapatkan NULL di mana Anda memiliki variabel block_encryption_mode yang disetel secara berbeda saat menyimpan dan mencoba mengambil nilainya, periksa apakah Anda tidak secara tidak sengaja kembali ke default 'aes-128-ebc di antara sesi. Mungkin ada yang lain...
Kueri kedua akan gagal karena Anda perlu menyediakan iv untuk fungsi enkripsi dan dekripsi, Anda hanya menggunakannya untuk mengenkripsi. Selain itu, karena Anda mengambil nilai dari MyTable, Encrypted_ID sudah akan dienkripsi dan efek dari kueri ini adalah mengenkripsinya lagi, sebelum membalikkannya agar Anda kembali ke nilai yang disimpan (terenkripsi).
Terakhir, AES hanya akan menggunakan 16 byte dari iv sehingga Anda mungkin juga membuat VARBINARY (16).