Всъщност няма нищо лошо в първата ви заявка, синтактично тя е на място, както показва този работещ пример.
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)
Що се отнася до защо не работи, успях да накарам заявката да върне NULL в 2 сценария. Първо, вие получавате върнато NULL, ако използвате различен iv за криптиране и декриптиране, така че може да искате да разгледате как съхранявате като iv. Второ, получавате NULL, когато имате различна променлива block_encryption_mode, когато съхранявате и се опитвате да извлечете стойността, проверете дали не се връщате случайно към 'aes-128-ebc по подразбиране между сесиите. Може да има и други...
Втората заявка ще се провали, защото трябва да предоставите iv на двете функции за криптиране и декриптиране, вие го използвате само за криптиране. Освен това, тъй като приемате стойностите от MyTable, Encrypted_ID вече ще бъде криптиран и ефектът от тази заявка ще бъде да го шифрова отново, преди да го обърне, за да ви върне обратно към съхранената (криптирана) стойност.
И накрая, AES ще използва само 16 байтове от iv, така че можете също да направите това VARBINARY(16).