如何安全地生成 AES CBC 加密的 IV?

发布于 2024-12-02 18:04:05 字数 514 浏览 1 评论 0原文

我从事一些加密方面的工作。

  • 我使用 AES 256 和 CBC 模式
  • 我使用 OPENSSL

我知道以下事项(来源 = 维基百科):

初始化向量应该是:

  • 唯一:对于使用给定密钥加密的任何消息不得重复 不可
  • 预测:观察到任何消息的攻击者消息数量及其 IV 应该没有信息来预测下一条消息,每比特的成功概率大于 50%(即,与随机的无法区分)

我的问题是,如何安全地生成 IV使用 OPENSSL 和 PHP?我知道lib mcrypt中有这样的功能(https://php .net/manual/en/function.mcrypt-create-iv.php

我没有找到任何可以使用 OPENSSL 执行此操作的内容(生成独特且不可预测的 IV)。

I work on some crypto stuff.

  • I use AES 256 with CBC mode
  • I use OPENSSL

I am aware of the following things (source = wikipedia):

an initalization vector should be:

  • Unique: must not be repeated for any message encrypted with a given key
  • Unpredictable: an attacker who observes any number of messages and their IVs should have no information to predict the next one with probability of success greater than 50% per bit (i.e., indistinguishable from random)

My question is, how to securely generate the IV with OPENSSL and PHP? I know there is such a functionnality in lib mcrypt (https://php.net/manual/en/function.mcrypt-create-iv.php)

I didn't find anything for doing this with OPENSSL (generating unique and unpredictable IV).

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

凑诗 2024-12-09 18:04:05

使用 openssl_random_pseudo_bytes (大多数最好将第二个参数设置为现有变量,然后您应该测试它是否设置为 TRUE)。这将生成具有适当随机性特征的 IV。

$wasItSecure = false;
$iv = openssl_random_pseudo_bytes(16, $wasItSecure);
if ($wasItSecure) {
    // We're good to go!
} else {
    // Insecure result. Fail closed, do not proceed.
}

另外,PHP 7 提供了更简单的 random_bytes()

Use openssl_random_pseudo_bytes (most preferably with the second parameter set to an existing variable, which you should then test that it was set to TRUE). This will generate IVs with appropriate randomness characteristics.

$wasItSecure = false;
$iv = openssl_random_pseudo_bytes(16, $wasItSecure);
if ($wasItSecure) {
    // We're good to go!
} else {
    // Insecure result. Fail closed, do not proceed.
}

Alternatively, PHP 7 offers random_bytes() which is much simpler.

手长情犹 2024-12-09 18:04:05

您可以使用openssl_random_pseudo_bytes(len, &crypto_stron)

第一个参数是您想要的长度(以字节为单位)。如果您将此用于开放式 ssl 方法之一,则可以使用函数 openssl_cipher_iv_length(method) 获取所用方法的正确长度。

第二个参数 &crypto_strong 允许您传入一个布尔变量,该变量将根据所使用的算法是否加密安全而设置为 true 或 false。然后您可以检查该变量并在该变量返回 false 时正确处理它。它永远不应该发生,但如果它发生了,你可能会想知道。

以下是正确使用的示例:

$method = 'aes-256-cbc';
$ivlen = openssl_cipher_iv_length($method);
$isCryptoStrong = false; // Will be set to true by the function if the algorithm used was cryptographically secure
$iv = openssl_random_pseudo_bytes($ivlen, $isCryptoStrong);
if(!$isCryptoStrong)
    throw new Exception("Non-cryptographically strong algorithm used for iv generation. This IV is not safe to use.");

有关详细信息,请参阅:

You can use openssl_random_pseudo_bytes(len, &crypto_stron).

The first parameter is the length you want in bytes. If you are using this for use in one of the open ssl methods, you can use the function openssl_cipher_iv_length(method) to get the correct length for the method used.

The second parameter, &crypto_strong, allows you to pass in a boolean variable that will be set to true or false depending on whether the algorithm used was cryptographically secure. You can then check this variable and handle it properly if the variable comes back false. It should never happen, but if it does then you will probably want to know.

Here is an example of proper usage:

$method = 'aes-256-cbc';
$ivlen = openssl_cipher_iv_length($method);
$isCryptoStrong = false; // Will be set to true by the function if the algorithm used was cryptographically secure
$iv = openssl_random_pseudo_bytes($ivlen, $isCryptoStrong);
if(!$isCryptoStrong)
    throw new Exception("Non-cryptographically strong algorithm used for iv generation. This IV is not safe to use.");

For more information see:

雨的味道风的声音 2024-12-09 18:04:05

使用 Thomas 所接受的相同的东西会更舒服:

private function genIv()
{
    $efforts = 0;
    $maxEfforts = 50;
    $wasItSecure = false;

    do
    {
        $efforts+=1;
        $iv = openssl_random_pseudo_bytes(16, $wasItSecure);
        if($efforts == $maxEfforts){
            throw new Exception('Unable to genereate secure iv.');
            break;
        }
    } while (!$wasItSecure);

    return $iv;
}

Just more comfortable to use the same stuff that Thomas sujested:

private function genIv()
{
    $efforts = 0;
    $maxEfforts = 50;
    $wasItSecure = false;

    do
    {
        $efforts+=1;
        $iv = openssl_random_pseudo_bytes(16, $wasItSecure);
        if($efforts == $maxEfforts){
            throw new Exception('Unable to genereate secure iv.');
            break;
        }
    } while (!$wasItSecure);

    return $iv;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文