Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/137.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 使用aes_256_cbc密码加密时默认的IV是什么?_C++_Encryption_Openssl_Aes_Block Cipher - Fatal编程技术网

C++ 使用aes_256_cbc密码加密时默认的IV是什么?

C++ 使用aes_256_cbc密码加密时默认的IV是什么?,c++,encryption,openssl,aes,block-cipher,C++,Encryption,Openssl,Aes,Block Cipher,我在一个文件中生成了一个随机的256位对称密钥,用于使用OpenSSL命令行加密某些数据,稍后需要使用OpenSSL库以编程方式对其进行解密。我没有成功,我认为问题可能在于我正在使用(或未使用)的初始化向量 我使用以下命令加密数据: /usr/bin/openssl enc -aes-256-cbc -salt -in input_filename -out output_filename -pass file:keyfile 我正在使用以下调用初始化数据的解密: EVP_DecryptIni

我在一个文件中生成了一个随机的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
是一个包含键的32字节的
向量。我的问题是关于最后一个参数。它应该是密码算法的初始化向量。加密时我没有指定IV,所以一定使用了一些默认值

为该参数传递nullptr是否意味着“使用默认值”?默认值为空,并且没有向第一个密码块添加任何内容


我应该提到,我可以在不提供IV的情况下从命令行解密。

EVP\u DecryptInit\u ex
是AES解密原语的接口。这只是解密OpenSSL加密格式所需的一部分。OpenSSL加密格式没有很好的文档记录,但是您可以从代码和一些文档中反向使用它。钥匙和IV计算在
EVP_BytesToKey
文档中解释:

   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.
这里的“散列”是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\uuuuuuuuuuuu
头,然后使用salt来计算密钥和IV。然后你就有了要输入
EVP\u DecryptInit\u ex
的片段

因为你在C++中这样做,你可以通过代码> Enc>代码>代码来重用它(在验证它的许可证与你的使用兼容)之后。 请注意,OpenSSL IV是随机生成的,因为它是包含随机salt的哈希过程的输出。第一个区块的安全性并不取决于IV本身是随机的;它只要求特定的IV+密钥对永远不要重复。OpenSSL过程可以确保,只要随机盐不再重复

以这种方式使用MD5可能会以泄露信息的方式缠绕密钥和IV,但我从未见过有分析声称这一点。如果您必须使用OpenSSL格式,我不会对它的IV代有任何犹豫。OpenSSL格式的最大问题是它很快就可以使用暴力(4轮MD5不够扩展),而且它缺乏任何身份验证

使用EVP_aes_256_cbc()[sic]密码加密时,默认的IV是什么…

为该参数传递nullptr是否意味着“使用默认值”?默认值为空,并且没有向第一个密码块添加任何内容

没有。你必须提供它。为了完整性,IV应该是不可预测的

“不可预测”与“唯一”和“随机”略有不同。例如,SSLv3使用最后一个密文块作为下一个块的IV。它是唯一的,但既不是随机的,也不是不可预测的,并且它使SSLv3容易受到选择的明文攻击

其他库做了一些聪明的事情,比如提供一个空向量(一个0的字符串)。袭击者为此感谢他们。另请参见关于堆栈溢出和关于Crypto.SE的内容


/usr/bin/openssl enc-aes-256-cbc…


我应该提到,我可以在不提供IV的情况下从命令行解密

OpenSSL使用一个内部mashup/key派生函数,该函数接受密码,并派生一个key和iv。它被调用,您可以在手册页中了解它。手册页还说:

如果总密钥和IV长度小于摘要长度且使用MD5,则派生算法与PKCS#5 v1.5兼容,否则使用非标准扩展来派生额外数据

一旦你知道要寻找什么,就有很多例子可以说明
EVP_BytesToKey
。在C中是一个,在Java中是一个


EVP_DecryptInit_ex(ctx,EVP_aes_256_cbc(),nullptr,keyfile.data(),nullptr))


加密时我没有指定IV,所以一定使用了一些默认值

检查您的返回值。呼叫应该在路径的某个地方失败。也许不是在
EVP\u DecryptInit\u ex
,但肯定是在
EVP\u decryptinfinal
之前


如果没有失败,请提交错误报告。

使用no IV(或固定默认值)不会严重破坏加密的强度吗?据我所知,IV的目的是确保相同的明文不会生成相同的密文。所以需要有一个IV,它不需要是秘密的,它只需要对你加密的所有东西都是唯一的。不使用密码(或固定密码)听起来是一个非常糟糕的主意。我不是密码专家,也不在电视上播放密码,所以我真的没有资格回答(因此,为什么上面只是一个评论)。作为一个非专家,我猜只要每次密钥都是唯一的,那么它可能就没问题了,但作为一个对加密知之甚少的实用主义者,无论如何,我可能也会使用随机IV,我发现了一些关于这方面的信息:这里的公认答案似乎与我最初的直觉一致,即使用固定IV会降低强度(在攻击者试图强行破解密钥的情况下)。所以每次我都会使用(真正的)随机IV,即使键是唯一的。@JesperJuhl-每种模式通常有不同的要求。CBC通常需要一个不可预测的IV。我更新了我的答案以提供参考。这不是失败