使用十六进制密钥解密 AES256 十六进制密文

Decrypting an AES256 hex ciphertext with a hex key

我已经生成了十六进制的 AES-256 密文 (cipher.hex),我正在尝试解密:

53 9B 33 3B 39 70 6D 14 90 28 CF E1 D9 D4 A4 07

对应的 256 位十六进制密钥 (key.hex):

80 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01

我首先尝试使用以下命令将两者解码为 base64:

base64 cipher.hex > input;
base64 key.hex > key;

最后,将它们传递给 openssl,如下所示:

openssl aes-256-cbc -d -a -pass file:key -in input -out out

此时我从 openssl 返回了“错误的幻数”,但没有任何关于哪里出了问题的指导。

我执行的程序有问题吗?我也尝试过将十六进制值转换为二进制...真的不确定要从十六进制给出 openssl 什么输入,更不用说 base64 解码换行符包装的十六进制是否有效。

您正在尝试对使用 ECB 和原始密钥加密的内容使用 CBC 和 password-based 加密。您还在使用 base64 编码 十六进制字符 ,而不是实际的字节。您正在编码 <ASCII for 5><ASCII for 3><ASCII for space>... 您想要编码 0x53、0x9B、0x33 等。无论如何这里都不需要 Base64。

首先,将您的十六进制输入转换为原始数据(不是 base64)。我喜欢 xxd 这个:

echo "53 9B 33 3B 39 70 6D 14 90 28 CF E1 D9 D4 A4 07" | xxd -r -p > input

接下来,您需要 openssl 喜欢的十六进制格式的密钥,没有空格或换行符:

KEY=$(echo "80 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01" | tr -d '[ \n]'

echo $KEY  
# prints 8000000000000000000000000000000000000000000000000000000000000001

现在,您可以解密数据(使用十六进制密钥的 aes-256-ecb):

openssl aes-256-ecb -d -in input -K $KEY | xxd

这会打印:

00000000: 8070 6050 4030 2010 0807 0605 0403 02    .p`P@0 ........

秩序井然,不会出错。 (0x80, 0x70, 0x60, 0x50, ...)

如果这是 CBC,就会有一个 IV,并且在大多数情况下是一个填充块。也就是说,对于没有填充和 NULL IV(你永远不应该使用)的单个块,CBC 等同于 ECB,因此可以将其解密为 CBC 并获得相同的结果:

openssl aes-256-cbc -iv 00000000000000000000000000000000 -d -in input -K $KEY | xxd

“错误的幻数”错误是因为您使用了 -pass 选项,该选项采用了 OpenSSL 的密码密钥派生算法。以这种方式加密的文件以 ASCII 序列 Salted__ 开头。缺少它,因此输入被拒绝。 (无论如何都行不通,因为这是用原始密钥加密的。)