我正在尝试使用Laravel的Crypt功能,只需将值存储在数据库中,稍后再使用即可。但是我注意到我无法解密这个值。
我的应用程序密钥是一个随机的32个字符的字符串。我的密码是MCRYPT_RIJNDAEL_128
。
从PHP信息中,安装了MCRYPT,并支持RIJNDAEL_128。
为了测试,我在GET rou上执行以下操作:
$t = "123456789";
var_dump(Crypt::encrypt($t));
请参阅:http://laravel.io/bin/2e9Xr#
在每次页面刷新时,输出是一个不同的值,这显然是不正确的 - 但我不知道为什么。
我正在使用EasyPHP作为我的开发服务器。但是我注意到的一件事是,与生产的Apache Web服务器相比,此环境中的应用程序请求显着缓慢。
这让我想知道每次是否有某种环境刷新,可能会重置MCRYPT用于加密的“资源”,因此每次都不同。
任何线索?
答案 0 :(得分:4)
这是正常行为。出于安全原因,每个Crypt :: encrypt调用都应该产生不同的输出。
Crypt对于小字符串来说效率非常低。例如,Crypt::encrypt("Hello World")
输出如下内容:eyJpdiI6Imhnb2hRazVabUNZUnVRVzFBSEExVkE9PSIsInZhbHVlIjoiTHJ4c05zcjdJZkZwWU1vRVVRMEcwZE5nTUdjQnhyM2RKWTMzSW04b1cxYz0iLCJtYWMiOiIyZjRmNDc3NGEyNGQyOGJjZGQ4MWQxYWViYzI1MjNjZTU0MmY4YTIxYTEyNWVjNDVlZDc4ZWEzNzRmN2QwM2ZiIn0=
立即可识别为基本64字符串。解码后,它变为{"iv":"hgohQk5ZmCYRuQW1AHA1VA==","value":"LrxsNsr7IfFpYMoEUQ0G0dNgMGcBxr3dJY33Im8oW1c=","mac":"2f4f4774a24d28bcdd81d1aebc2523ce542f8a21a125ec45ed78ea374f7d03fb"}
使用Crypt,您可以轻松加密和解密大型明文,而无需担心细节。但是,如果您想存储或传输大量单独加密的实体,那么您可能需要考虑不同的方法。
(注意:目录结构对Laravel 4.2有效。)
首先,大多数安全块密码操作模式需要IV (initialization vector),这是一组长度与块大小匹配的随机字节。对每个密文使用不同的IV对于阻止密码分析和重放攻击非常重要。但是,让我们看看实际的Crypt代码。
从config/app.php
别名数组开始,我们看到'Crypt' => 'Illuminate\Support\Facades\Crypt'
所以我们检查vendor/laravel/framework/src/Support/Facades
目录,我们发现Crypt.php
表示模块访问者名称实际上是" encrypter"。检查config/app.php
提供程序数组会显示'Illuminate\Encryption\EncryptionServiceProvider'
。
vendor/laravel/framework/src/Illuminate/Encryption
有几个感兴趣的文件:Encrypter.php
和EncryptionServiceProvider.php
。服务提供者使用创建,配置和返回Encrypter
实例的函数绑定访问者。
在Encrypter
课程中,我们找到了加密方法:
public function encrypt($value)
{
$iv = mcrypt_create_iv($this->getIvSize(), $this->getRandomizer());
$value = base64_encode($this->padAndMcrypt($value, $iv));
// Once we have the encrypted value we will go ahead base64_encode the input
// vector and create the MAC for the encrypted value so we can verify its
// authenticity. Then, we'll JSON encode the data in a "payload" array.
$mac = $this->hash($iv = base64_encode($iv), $value);
return base64_encode(json_encode(compact('iv', 'value', 'mac')));
}
你有它。每次调用Crypt::encrypt
时,它都会生成一个新的IV,加密该值,创建一个MAC的IV和密文,然后返回一个基本的64位编码的JSON字符串,该字符串是IV的关联数组, MAC和密文。每个IV都是不同的,这意味着每个密文和MAC也会不同 - 即使是相同的值。如果所有明文都很大,那么真的很聪明,但对于许多较小的明文来说非常不切实际,因为MAC是不必要的开销。
为每个加密调用生成16字节的随机性,并将其级联到密文和MAC中,所有这些都在基本64位编码的JSON关联数组中返回。因此,每个Crypt :: encrypt调用都会产生不同的输出。
答案 1 :(得分:0)
mcrypt的工作方式 - http://mnshankar.wordpress.com/2014/03/29/laravel-hash-make-explained/
$test = 'test';
$crypted = Crypt::encrypt($test);
echo $crypted.'<br />'; // encrypted string
echo Crypt::decrypt($crypted); // "test"