首先,您可以稍后再考虑填充。像您所做的那样提供0 意味着没有填充的AES CBC,并且通过该配置,您应该可以很好地看到您的消息。 Albiet 最后可能带有一些填充字节。这样就离开了:
- 您没有正确加载密钥。
- 您没有正确加载 IV。
- 您没有正确加载数据。
- 服务器正在做一些你意想不到的事情。
要调试它,您需要隔离您的系统。您可以通过实施一个环回测试来做到这一点,在该测试中,您都加密然后解密数据,以确保您正确加载所有内容。但这可能会产生误导。即使您做错了什么(例如,向后加载密钥),您仍然可以解密您加密的内容,因为您在双方都以完全相同的错误方式进行操作。
因此,您需要针对 Known Answer Tests (KAT) 进行测试。您可以在AES wikipedia entry 上查找官方 KAT。但碰巧我在这里发布了another answer,我们可以使用。
鉴于此输入:
KEY: 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f
IV: 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
PLAIN TEXT: encrypt me
CIPHER TEXT: 338d2a9e28208cad84c457eb9bd91c81
通过第三方程序验证您可以解密密文并获取纯文本。
$ echo -n "encrypt me" > to_encrypt
$ openssl enc -in to_encrypt -out encrypted -e -aes-256-cbc \
> -K 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f \
> -iv 0000000000000000
$ hexdump -C encrypted
00000000 33 8d 2a 9e 28 20 8c ad 84 c4 57 eb 9b d9 1c 81 |3.*.( ....W.....|
00000010
$ openssl enc -in encrypted -out plain_text -d -aes-256-cbc \
> -K 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f \
> -iv 0000000000000000
$ hexdump -C plain_text
00000000 65 6e 63 72 79 70 74 20 6d 65 |encrypt me|
0000000a
所以现在尝试在您的程序中解密这个已知答案测试。确保启用 PKCS7 填充,因为这就是我在本示例中使用的。作为一个练习,在没有填充的情况下解密它,看看结果是一样的,除了在“加密我”文本之后有填充字节。
实施 KAT 是一大步。它说您的实现是正确的,但是您对服务器行为的假设是错误的。然后是时候开始质疑这些假设了......
(和 PS,你提到的那些选项不是相互排斥的。ECB 表示没有 IV,CBC 表示你有 IV。与填充无关。)
好的,我知道我说这是一个练习,但我想证明即使你使用填充加密
并在没有填充的情况下解密,您不会得到垃圾。因此,鉴于使用 PKCS7 填充的 KAT,我们使用 no padding 选项对其进行解密,并获得一条可读消息,后跟 06 用作填充字节。
$ openssl enc -in encrypted -out plain_text -d -aes-256-cbc \
-K 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f \
-iv 0000000000000000 -nopad
$ hexdump -C plain_text
00000000 65 6e 63 72 79 70 74 20 6d 65 06 06 06 06 06 06 |encrypt me......|
00000010
$