亲爱的 openSSL 爱好者,
我对使用 openSSL 加密有疑问。
$ openssl enc -e -aes-256-cbc -pbkdf2 -iter 10000 -a -k "secret-passphrase" -S 3030303030303030 -P
salt=3030303030303030
key=4308510484954F2C45965C7EE57655A016261037628F8E25E0C44B746217B805
iv =A1B59BE16D6AABD8C7B953E4D7D7514B
$ 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
$ 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?
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