Na vašem prvním dotazu ve skutečnosti není nic špatného, syntakticky je na správném místě, jak ukazuje tento příklad.
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)
Pokud jde o to, proč to nefunguje, podařilo se mi přimět dotaz, aby vrátil NULL ve 2 scénářích. Za prvé, dostanete NULL, pokud použijete pro šifrování a dešifrování jiný iv, takže se možná budete chtít podívat na to, jak ukládáte jako iv. Za druhé, dostanete NULL tam, kde máte proměnnou block_encryption_mode nastavenou odlišně při ukládání a pokusu o načtení hodnoty, zkontrolujte, zda se mezi relacemi náhodně nevracíte k výchozímu 'aes-128-ebc. Mohou existovat další...
Druhý dotaz selže, protože potřebujete dodat iv jak pro šifrovací, tak dešifrovací funkce, používáte jej pouze k šifrování. Protože přebíráte hodnoty z MyTable, Encrypted_ID již bude zašifrováno a výsledkem tohoto dotazu by bylo jeho opětovné zašifrování, než to obrátíte, abyste se dostali zpět k uložené (zašifrované) hodnotě.
Konečně, AES bude používat pouze 16 bajtů iv, takže můžete také udělat VARBINARY(16).