使用 aes_256_cbc 密码加密时的默认 IV 是多少?
What is the default IV when encrypting with aes_256_cbc cipher?
我在一个文件中生成了一个随机的 256 位对称密钥,用于使用 OpenSSL 命令行加密一些数据,稍后我需要使用 OpenSSL 库以编程方式解密这些数据。我没有成功,我认为问题可能出在我正在使用(或未使用)的初始化向量中。
我使用这个命令加密数据:
/usr/bin/openssl enc -aes-256-cbc -salt -in input_filename -out output_filename -pass file:keyfile
我正在使用以下调用来初始化数据解密:
EVP_DecryptInit_ex(ctx, EVP_aes_256_cbc(), nullptr, keyfile.data(), nullptr))
keyfile
是一个 vector<unsigned char>
,它保存了密钥的 32 个字节。我的问题是关于最后一个参数。它应该是密码算法的初始化向量。加密时我没有指定 IV,因此一定使用了一些默认值。
为该参数传递 nullptr 是否意味着 "use the default"?默认为null,第一个密码块什么都不加?
我应该提一下,我可以在不提供 IV 的情况下从命令行解密。
EVP_DecryptInit_ex
是 AES 解密原语的接口。这只是解密 OpenSSL 加密格式所需的一部分。 OpenSSL 加密格式没有很好的文档记录,但您可以从代码和一些文档中逆向使用它。 EVP_BytesToKey
文档中解释了密钥和 IV 计算:
The key and IV is derived by concatenating D_1, D_2, etc until enough
data is available for the key and IV. D_i is defined as:
D_i = HASH^count(D_(i-1) || data || salt)
where || denotes concatentaion, D_0 is empty, HASH is the digest
algorithm in use, HASH^1(data) is simply HASH(data), HASH^2(data) is
HASH(HASH(data)) and so on.
The initial bytes are used for the key and the subsequent bytes for the
IV.
"HASH"这里是MD5。实际上,这意味着您可以像这样计算哈希值:
Hash0 = ''
Hash1 = MD5(Hash0 + Password + Salt)
Hash2 = MD5(Hash1 + Password + Salt)
Hash3 = MD5(Hash2 + Password + Salt)
...
然后提取密钥所需的字节,然后提取 IV 所需的字节。对于 AES-128,这意味着 Hash1 是密钥,Hash2 是 IV。对于 AES-256,密钥是 Hash1+Hash2(串联,未添加),Hash3 是 IV。
您需要去掉前导 Salted___
header,然后使用盐来计算密钥和 IV。然后你就可以将碎片输入 EVP_DecryptInit_ex
.
不过,由于您是在 C++ 中执行此操作,因此您可能只需挖掘 enc
代码并重新使用它(在验证其许可证与您的使用兼容之后)。
请注意,OpenSSL IV 是随机生成的,因为它是涉及随机盐的散列过程的输出。第一个块的安全性不依赖于 IV 本身是随机的;它只要求永不重复特定的 IV+Key 对。 OpenSSL 过程确保只要随机盐从不重复。
以这种方式使用 MD5 可能会以泄露信息的方式纠缠密钥和 IV,但我从未见过声称如此的分析。如果您必须使用 OpenSSL 格式,我会毫不犹豫地选择它的 IV 代。 OpenSSL 格式的最大问题是它的暴力破解速度很快(4 轮 MD5 不够拉伸)并且它缺乏任何身份验证。
What is the default IV when encrypting with EVP_aes_256_cbc() [sic] cipher...
Does passing nullptr for that parameter mean "use the default"? Is the default null, and nothing is added to the first cipher block?
有none。你必须提供它。为了完整起见,IV 应该是不可预测的。
Non-Predictable 与 Unique 和 Random 略有不同。例如,SSLv3 曾经使用最后一个密文块作为下一个块的 IV。它是 Unique,但既不是 Random 也不是 Non-Predictable,它使 SSLv3 易受攻击选择明文攻击。
其他库会做一些聪明的事情,比如提供一个空向量(一串 0)。他们的攻击者为此感谢他们。另请参阅 Crypto.SE 上的 Why is using a Non-Random IV with CBC Mode a vulnerability? on Stack Overflow and Is AES in CBC mode secure if a known and/or fixed IV is used?。
/usr/bin/openssl enc -aes-256-cbc...
I should mention that I'm able to decrypt from the command line without supplying an IV.
OpenSSL 使用内部 mashup/key 派生函数获取密码,并派生密钥和 iv。它称为 EVP_BytesToKey
,您可以在手册页中阅读它。手册页还说:
If the total key and IV length is less than the digest length and MD5 is used then the derivation algorithm is compatible with PKCS#5 v1.5 otherwise a non standard extension is used to derive the extra data.
一旦您知道要查找的内容,就会有很多 EVP_BytesToKey
的示例。 Openssl password to key is one in C. How to decrypt file in Java encrypted with openssl command using AES 合一 Java.
EVP_DecryptInit_ex(ctx, EVP_aes_256_cbc(), nullptr, keyfile.data(), nullptr))
I didn't specify an IV when encrypting, so some default must have been used.
检查您的 return 值。呼叫应该在路径的某处失败。也许不在 EVP_DecryptInit_ex
,但肯定在 EVP_DecryptFinal
.
之前
如果没有失败,请提交错误报告。
我在一个文件中生成了一个随机的 256 位对称密钥,用于使用 OpenSSL 命令行加密一些数据,稍后我需要使用 OpenSSL 库以编程方式解密这些数据。我没有成功,我认为问题可能出在我正在使用(或未使用)的初始化向量中。
我使用这个命令加密数据:
/usr/bin/openssl enc -aes-256-cbc -salt -in input_filename -out output_filename -pass file:keyfile
我正在使用以下调用来初始化数据解密:
EVP_DecryptInit_ex(ctx, EVP_aes_256_cbc(), nullptr, keyfile.data(), nullptr))
keyfile
是一个 vector<unsigned char>
,它保存了密钥的 32 个字节。我的问题是关于最后一个参数。它应该是密码算法的初始化向量。加密时我没有指定 IV,因此一定使用了一些默认值。
为该参数传递 nullptr 是否意味着 "use the default"?默认为null,第一个密码块什么都不加?
我应该提一下,我可以在不提供 IV 的情况下从命令行解密。
EVP_DecryptInit_ex
是 AES 解密原语的接口。这只是解密 OpenSSL 加密格式所需的一部分。 OpenSSL 加密格式没有很好的文档记录,但您可以从代码和一些文档中逆向使用它。 EVP_BytesToKey
文档中解释了密钥和 IV 计算:
The key and IV is derived by concatenating D_1, D_2, etc until enough
data is available for the key and IV. D_i is defined as:
D_i = HASH^count(D_(i-1) || data || salt)
where || denotes concatentaion, D_0 is empty, HASH is the digest
algorithm in use, HASH^1(data) is simply HASH(data), HASH^2(data) is
HASH(HASH(data)) and so on.
The initial bytes are used for the key and the subsequent bytes for the
IV.
"HASH"这里是MD5。实际上,这意味着您可以像这样计算哈希值:
Hash0 = ''
Hash1 = MD5(Hash0 + Password + Salt)
Hash2 = MD5(Hash1 + Password + Salt)
Hash3 = MD5(Hash2 + Password + Salt)
...
然后提取密钥所需的字节,然后提取 IV 所需的字节。对于 AES-128,这意味着 Hash1 是密钥,Hash2 是 IV。对于 AES-256,密钥是 Hash1+Hash2(串联,未添加),Hash3 是 IV。
您需要去掉前导 Salted___
header,然后使用盐来计算密钥和 IV。然后你就可以将碎片输入 EVP_DecryptInit_ex
.
不过,由于您是在 C++ 中执行此操作,因此您可能只需挖掘 enc
代码并重新使用它(在验证其许可证与您的使用兼容之后)。
请注意,OpenSSL IV 是随机生成的,因为它是涉及随机盐的散列过程的输出。第一个块的安全性不依赖于 IV 本身是随机的;它只要求永不重复特定的 IV+Key 对。 OpenSSL 过程确保只要随机盐从不重复。
以这种方式使用 MD5 可能会以泄露信息的方式纠缠密钥和 IV,但我从未见过声称如此的分析。如果您必须使用 OpenSSL 格式,我会毫不犹豫地选择它的 IV 代。 OpenSSL 格式的最大问题是它的暴力破解速度很快(4 轮 MD5 不够拉伸)并且它缺乏任何身份验证。
What is the default IV when encrypting with EVP_aes_256_cbc() [sic] cipher...
Does passing nullptr for that parameter mean "use the default"? Is the default null, and nothing is added to the first cipher block?
有none。你必须提供它。为了完整起见,IV 应该是不可预测的。
Non-Predictable 与 Unique 和 Random 略有不同。例如,SSLv3 曾经使用最后一个密文块作为下一个块的 IV。它是 Unique,但既不是 Random 也不是 Non-Predictable,它使 SSLv3 易受攻击选择明文攻击。
其他库会做一些聪明的事情,比如提供一个空向量(一串 0)。他们的攻击者为此感谢他们。另请参阅 Crypto.SE 上的 Why is using a Non-Random IV with CBC Mode a vulnerability? on Stack Overflow and Is AES in CBC mode secure if a known and/or fixed IV is used?。
/usr/bin/openssl enc -aes-256-cbc...
I should mention that I'm able to decrypt from the command line without supplying an IV.
OpenSSL 使用内部 mashup/key 派生函数获取密码,并派生密钥和 iv。它称为 EVP_BytesToKey
,您可以在手册页中阅读它。手册页还说:
If the total key and IV length is less than the digest length and MD5 is used then the derivation algorithm is compatible with PKCS#5 v1.5 otherwise a non standard extension is used to derive the extra data.
一旦您知道要查找的内容,就会有很多 EVP_BytesToKey
的示例。 Openssl password to key is one in C. How to decrypt file in Java encrypted with openssl command using AES 合一 Java.
EVP_DecryptInit_ex(ctx, EVP_aes_256_cbc(), nullptr, keyfile.data(), nullptr))
I didn't specify an IV when encrypting, so some default must have been used.
检查您的 return 值。呼叫应该在路径的某处失败。也许不在 EVP_DecryptInit_ex
,但肯定在 EVP_DecryptFinal
.
如果没有失败,请提交错误报告。