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

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

问题描述

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

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?

我知道我可以做更多的Google搜索工作,但是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(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都是唯一的,并且影响了加密过程,因此最终结果也很独特.约翰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


For more info, check out PHP's Mcrypt library. It's quite full featured and has tons of examples, many of which can help you out with openssh encryption implementations. http://php.net/manual/en/function.mcrypt-encrypt.php

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

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