Na verdade, não há nada de errado com sua primeira consulta, sintaticamente ela está correta, como demonstra este exemplo trabalhado.
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)
Quanto ao motivo de não estar funcionando, consegui que a consulta retornasse NULL em 2 cenários. Um, você obtém NULL retornado se usar um iv diferente para criptografia e descriptografia, então você pode querer ver como está armazenando como o iv. Dois, você obtém NULL onde você tem a variável block_encryption_mode definida de forma diferente ao armazenar e tentar recuperar o valor, verifique se você não está revertendo acidentalmente para o padrão 'aes-128-ebc entre as sessões. Pode haver outros...
A segunda consulta falhará porque você precisa fornecer o iv para ambas as funções de criptografia e descriptografia, você só o usa para criptografar. Além disso, como você está obtendo os valores da MyTable, o Encrypted_ID já estará criptografado e o efeito dessa consulta seria criptografá-lo novamente, antes de reverter isso para retornar ao valor armazenado (criptografado).
Por fim, o AES usará apenas 16 bytes do iv então você também pode fazer esse VARBINARY(16).