openssl_encrypt中初始化向量的使用 [英] Use of Initialization Vector in openssl_encrypt

查看:33
本文介绍了openssl_encrypt中初始化向量的使用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我看了这个问题,并想为自己做.当我运行此代码时(直接取自 this answer):

I had a look at this question, and wanted to do it for myself. When I ran this code (taken straight from this answer):

$textToEncrypt = "My super secret information.";
$encryptionMethod = "AES-256-CBC";  // AES is used by the U.S. gov't to encrypt top secret documents.
$secretHash = "25c6c7ff35b9979b151f2136cd13b0ff";

//To encrypt
$encryptedMessage = openssl_encrypt($textToEncrypt, $encryptionMethod, $secretHash, '1234567812345678');

//To Decrypt
$decryptedMessage = openssl_decrypt($encryptedMessage, $encryptionMethod, $secretHash);

//Result
echo "Encrypted: $encryptedMessage <br>Decrypted: $decryptedMessage";

但是我收到警告

openssl_encrypt(): Using an empty Initialization Vector (iv) is potentially insecure and not recommended

所以我去看了文档,但没有文档".我发现了这个评论,但仍然没有提到什么初始化向量应该是以及我应该如何使用它.谁能给我指点一下?

So I went and had a look at the docs, but there 'is no documentation'. I found this comment, but still no mention of what the Initialization Vector should be and how I should use it. Can anyone enlighten me?

我知道我可以做更多的谷歌搜索,但 Stackoverflow 在如此多的搜索结果中排名第一,我认为这个问题可能对遇到此问题的其他人有用.

I know I could have done some more Googleing, but Stackoverflow comes up first in so many search results I thought this question might be useful to anyone else who was having this problem.

推荐答案

IV 通常是一个随机数,可以保证加密文本的唯一性.

An IV is generally a random number that guarantees the encrypted text is unique.

为了解释为什么需要它,让我们假设我们有一个用密钥秘密"加密的人名数据库,没有 IV.

To explain why it's needed, let's pretend we have a database of people's names encrypted with the key 'secret' and no IV.

1 John dsfa9p8y098hasdf
2 Paul po43pokdfgpo3k4y
3 John dsfa9p8y098hasdf

如果 John 1 知道他的密文 (dsfa9p8y098hasdf) 并且可以访问其他密文,他可以轻松找到其他名为 John 的人.

If John 1 knows his cipher text (dsfa9p8y098hasdf) and has access to the other cipher texts, he can easily find other people named John.

现在实际上,需要 IV 的加密模式将始终使用 IV.如果您不指定 IV,它会自动设置为一堆空字节.想象一下第一个例子,但有一个常数 IV (00000000).

Now in actuality, an encryption mode that requires an IV will always use one. If you don't specify an IV, it's automatically set to a bunch of null bytes. Imagine the first example but with a constant IV (00000000).

1 John dsfa9p8y098hasdf 00000000
2 Paul po43pokdfgpo3k4y 00000000
3 John dsfa9p8y098hasdf 00000000

为了防止重复的密文,我们可以使用相同的秘密"密钥和随机 IV 来加密名称:

To prevent repeated cipher texts, we can encrypt the names using the same 'secret' key and random IV's:

1 John sdf875n90mh28458 45gh3546
2 Paul fg9087n5b60987nf 56897ngq
3 John gjhn0m89456vnler 8907345f

如您所见,两个John"密文现在不同了.每个 IV 都是独一无二的,并且影响了加密过程,从而使最终结果也是独一无二的.John 1 现在不知道用户 3 的名字是什么.

As you can see, the two 'John' cipher texts are now different. Each IV is unique and has influenced the encryption process making the end result unique as well. John 1 now has no idea what user 3's name is.

解密需要使用与加密文本相同的 IV,这就是为什么它必须存储在数据库中的原因.没有密钥,IV 是没有用的,因此与加密文本一起传输或存储它是无关紧要的.

Decryption requires the use of the same IV the text was encrypted with of course, which is why it must be stored in the database. The IV is of no use without the key so transmitting or storing it with the encrypted text is of no concern.

这是一个过于简单的例子,但事实是,不使用 IV 会产生严重的安全后果.

This is an overly simplistic example, but the truth is, not using IV's has serious security ramifications.

现在您的代码似乎正在设置 IV (1234567812345678),但没有在解密时使用它.那肯定会失败.

Now your code appears to be setting the IV (1234567812345678) but not using it on decryption. That's certain to fail.

您可能还想使用一些 PHP 的 IV 生成函数.我认为这应该对你有用:

You also may want to utilize some of PHP's IV generation functions. I think this should work for you:

$iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC);
$iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
$encryptedMessage = openssl_encrypt($textToEncrypt, $encryptionMethod, $secretHash, 0, $iv);
$decryptedMessage = openssl_decrypt($encryptedMessage, $encryptionMethod, $secretHash, 0, $iv);

对于存储/传输,您可以像这样简单地连接 IV 和密文:

For storage/transmission, you can simply concatenate the IV and cipher text like so:

$data = $iv.$encryptedMessage;

然后在检索时,拉出 IV 进行解密:

Then on retrieval, pull the IV out for decryption:

$iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC);
$iv = substr($data, 0, $iv_size);
$decryptedMessage = openssl_decrypt(substr($data, $iv_size), $encryptionMethod, $secretHash, 0, $iv);

<小时>

有关更多信息,请查看 PHP 的 Mcrypt 库.它功能齐全,有大量示例,其中许多可以帮助您实现 openssh 加密.http://php.net/manual/en/function.mcrypt-encrypt.php

这篇关于openssl_encrypt中初始化向量的使用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆