使用 AES-256-CBC 的 openSSL CLI 加密

问题描述 投票:0回答:1

亲爱的 openSSL 爱好者,

我对使用 openSSL 加密有疑问。

  1. 假设我有“秘密密码”和 salt='00000000'(十六进制相当于'3030303030303030'),并且我想使用 pbkdf2 进行 10000 次迭代和将在 aes-256-cbc 中使用的 sha256 哈希。为了从中得到 (key, iv) 对,我执行以下操作:
$ openssl enc -e -aes-256-cbc -pbkdf2 -iter 10000 -a -k "secret-passphrase" -S 3030303030303030 -P
salt=3030303030303030
key=4308510484954F2C45965C7EE57655A016261037628F8E25E0C44B746217B805
iv =A1B59BE16D6AABD8C7B953E4D7D7514B
  1. 现在假设我要加密 '0000000000000000'
$ openssl enc -e -aes-256-cbc -pbkdf2 -iter 10000 -a -k "secret-passphrase" -S 3030303030303030 -v <<< '0000000000000000'
bufsize=8192
U2FsdGVkX18wMDAwMDAwMBqMQ8GU/iXU+NBj3NT6lF72hdiq/vECsiGIyk6gzC3S
bytes read   :       17
bytes written:       65
  1. 现在使用步骤 1 中的 (key, iv) 进行步骤 2。
$ openssl enc -e -aes-256-cbc -K '4308510484954F2C45965C7EE57655A016261037628F8E25E0C44B746217B805' -iv 'A1B59BE16D6AABD8C7B953E4D7D7514B' -base64  -v <<< '0000000000000000'
bufsize=8192
GoxDwZT+JdT40GPc1PqUXvaF2Kr+8QKyIYjKTqDMLdI=
bytes read   :       17
bytes written:       45

在这两种情况下解密都能正确工作:

$ openssl enc -d -aes-256-cbc -K '4308510484954F2C45965C7EE57655A016261037628F8E25E0C44B746217B805' -iv 'A1B59BE16D6AABD8C7B953E4D7D7514B' -base64  -v <<< 'GoxDwZT+JdT40GPc1PqUXvaF2Kr+8QKyIYjKTqDMLdI='
bufsize=8192
0000000000000000
bytes read   :       45
bytes written:       17

$ openssl enc -d -aes-256-cbc -pbkdf2 -iter 10000 -a -k "secret-passphrase" -S 3030303030303030 -v <<< 'U2FsdGVkX18wMDAwMDAwMBqMQ8GU/iXU+NBj3NT6lF72hdiq/vECsiGIyk6gzC3S'
bufsize=8192
0000000000000000
bytes read   :       65
bytes written:       17

Q1. 为什么步骤1-2和步骤3的结果不一样?

Q2. 我可以控制“写入的字节数”长度吗?如果是的话,怎么办?

Q3. 如果要加密的消息的大小与输入缓冲区的大小不相等,那么如何调整?如果是这种情况,会添加哪些字节?用零字节填充? 当我使用 15 '0' 时,我会读取 16 个字节,如下所示(我尝试强制使用 16 字节 bufsize,但似乎 80 是最小值)。下面这两个的区别在于“nopad”选项。为什么?这里不是 16 字节的倍数吗?

$ openssl enc -e -aes-256-cbc -md sha512 -pbkdf2 -iter 10000 -a -k "secret-passphrase" -S 3030303030303030 -v -bufsize 16 -nopad <<< '000000000000000'
bufsize=80
U2FsdGVkX18wMDAwMDAwMBXbmH9q6kra/uzuL4MARoY=
bytes read   :       16
bytes written:       45

$ openssl enc -e -aes-256-cbc -md sha512 -pbkdf2 -iter 10000 -a -k "secret-passphrase" -S 3030303030303030 -v -bufsize 16 <<< '000000000000000'
bufsize=80
U2FsdGVkX18wMDAwMDAwMBXbmH9q6kra/uzuL4MARoaVlPlc2JL/k6Rdp00EQK8N
bytes read   :       16
bytes written:       65

Q4. 上例中要加密的消息长度为 16 字节。为什么“读取的字节数”是17? 看起来 15 个“0”相当于 16 个字节。也许添加了 eol?

encryption openssl aes
1个回答
0
投票

Q1。为什么步骤1-2和步骤3的结果不一样?

第一个示例包含提供盐的 OpenSSL 标头:

$ echo U2FsdGVkX18wMDAwMDAwMBqMQ8GU/iXU+NBj3NT6lF72hdiq/vECsiGIyk6gzC3S | base64 -D | xxd
00000000: 5361 6c74 6564 5f5f 3030 3030 3030 3030  Salted__00000000
00000010: 1a8c 43c1 94fe 25d4 f8d0 63dc d4fa 945e  ..C...%...c....^
00000020: f685 d8aa fef1 02b2 2188 ca4e a0cc 2dd2  ........!..N..-.

第二个没有标题,因为您提供了原始值。但正如您所期望的,它是相同的加密有效负载:

$ echo GoxDwZT+JdT40GPc1PqUXvaF2Kr+8QKyIYjKTqDMLdI= | base64 -D | xxd
00000000: 1a8c 43c1 94fe 25d4 f8d0 63dc d4fa 945e  ..C...%...c....^
00000010: f685 d8aa fef1 02b2 2188 ca4e a0cc 2dd2  ........!..N..-.

Q2。我可以控制“写入的字节数”长度吗?如果是的话,怎么办?

这个问题不清楚。显然,如果有效负载大小不同,您可以写入不同数量的字节。对于给定的有效负载和给定的一组参数,它始终是相同的。

Q3。 基本上,“填充是如何完成的?”

OpenSSL(和大多数系统)使用 PKCS#7 算法(由于历史原因,有时称为 PKCS#5)。

填充值是填充字节数。因此,如果需要 1 个字节的填充,则填充为“01”。如果填充 2 个字节,则为“02 02”。

Q4。为什么“读取字节数”是 17?

鉴于这一行:

$ openssl ... <<< '0000000000000000'

您正在使用here-string语法(可能来自zsh)。这被记录为:

对word进行shell扩展,并将结果传递到标准输入。这称为此处字符串。比较上面here-documents中word的使用,其中word没有经过shell扩展。 结果后面会有一个尾随换行符。

因此您的输入是十六个“0”字符,后跟一个换行符,即 17 个字节。

也许你想要:

$ echo -n '0000000000000000' | openssl enc -e -aes-256-cbc -pbkdf2 -iter 10000 -a -k "secret-passphrase" -S 3030303030303030 -v
bufsize=8192
GoxDwZT+JdT40GPc1PqUXuE33FyWfCN+0L4c8+GN5Bc=
bytes read   :       16
bytes written:       45
© www.soinside.com 2019 - 2024. All rights reserved.