我遇到 MariaDB 和 SCV Crypto Manager 生成的 AES-256-CBC 加密结果之间的差异。以下是我的设置详细信息以及我遵循的步骤:
加密参数 密钥:在 MariaDB 中使用 SHA2() 生成的 256 位密钥。 IV(初始化向量):16 字节向量,从 Base64 转换为二进制。 数据:我要加密的明文输入。
SET block_encryption_mode = 'aes-256-cbc';
SET @key = SHA2('JImgFdqERWjqyDaAwxIER0KbThoWV7GEiwSr0d6J2IQ=', 256);
SET @iv = UNHEX('557169695444544577516D6C4B30344A');
SET @plain_data = 'KTC';
SET @encrypted_data = UNHEX('116A82BE96082F6188F448B2FA49717B');
SELECT
HEX(AES_ENCRYPT(@plain_data, @key, @iv)) AS encrypted_hex, -- ENC
AES_DECRYPT(@encrypted_data, @key, @iv) AS decrypted_text, -- DEC
(@key) AS encryption_key_hex, -- KEY
(@iv) AS initialization_vector_hex; -- IV
Output:
+----------------------------------+----------------+------------------------------------------------------------------+---------------------------+
| encrypted_hex | decrypted_text | encryption_key_hex | initialization_vector_hex |
+----------------------------------+----------------+------------------------------------------------------------------+---------------------------+
| 116A82BE96082F6188F448B2FA49717B | KTC | db31652dbe04f6187e79cfb9c9bffb8e560a5a8eeec687e4c37a12815c4affbd | UqiiTDTEwQmlK04J |
+----------------------------------+----------------+------------------------------------------------------------------+---------------------------+
我使用 SCV CryptoManager 得到了下面的结果
Input : 11 6A 82 BE 96 08 2F 61 88 F4 48 B2 FA 49 71 7B
Modes : CBC
Key : db 31 65 2d be 04 f6 18 7e 79 cf b9 c9 bf fb 8e 56 0a 5a 8e ee c6 87 e4 c3 7a 12 81 5c 4a ff bd
IV : 55 71 69 69 54 44 54 45 77 51 6D 6C 4B 30 34 4A
AES mode CBC deciphering :
6A C6 0B FB D5 72 10 6D A4 EC B2 08 0D C1 32 F0
解码为ascii是jÆûÕrm¤ì²Á2ð
所以我真的很想知道为什么 MariaDB 和 SCV Crypto Manager 之间的加密结果不同,即使密钥、IV 和数据相同?
强烈建议始终使用具有所需密钥长度的密钥:
不幸的是,MariaDB(还有 MySQL)不会抱怨无效的密钥长度,而是执行以下操作:
如果密钥长度短于所需的密钥长度,则用零(0x0)填充:
select @@block_encryption_mode;
+-------------------------+
| @@block_encryption_mode |
+-------------------------+
| aes-128-cbc |
+-------------------------+
set @iv=0x3DAFBA429D9EB430B422DA802C9FAC41,
@key1=0x06A9214036B8A15B512E03D534120000,
@key2=0x06A9214036B8A15B512E03D53412;
select aes_encrypt("Test", @key1, @iv) = aes_encrypt("Test", @key2, @iv);
+-------------------------------------------------------------------+
| aes_encrypt("Test", @key1, @iv) = aes_encrypt("Test", @key2, @iv) |
+-------------------------------------------------------------------+
| 1 |
+-------------------------------------------------------------------+
如果密钥长度高于所需的密钥长度,MariaDB 会用冗余字节异或密钥,而其他实现会截断密钥,这可能是导致不同结果的原因。
#due xor operation with redundant bytes keys will be the same
set @key1=REPEAT("A",32), @key2=REPEAT("B",32);
select aes_encrypt("Test", @key1, @iv) = aes_encrypt("Test", @key2, @iv);
+-------------------------------------------------------------------+
| aes_encrypt("Test", @key1, @iv) = aes_encrypt("Test", @key2, @iv) |
+-------------------------------------------------------------------+
| 1 |
+-------------------------------------------------------------------+