Laravel 5加密 - 相同字符串给出不同的值?

3
我正在使用Laravel 5,并为一个项目做准备。其中一个要求是系统中存储的电子邮件必须经过加密。我正在使用Laravel 5的外观,以及相关的和方法。
问题在于,即使给出相同的字符串,加密后的值似乎不同。起初,我认为这可能与字段最大长度有关,但两个哈希值都在字段上设置的255长度以下。
例如,看看这个转储;
PHP
    $hash1 = 'eyJpdiI6InJFNTFkdktpVU9cL1wvRTJPVk94SURiUT09IiwidmFsdWUiOiJIZVh4Y1NyUGpVcTVFVTNSbWdUNnJCUWRHSGZTcnFTQWJKa1h0Q1wvMEVtZnFuM3dDeFwvXC9hdUs4enFXXC94dEJ0cSIsIm1hYyI6IjFjNjZjODFjMjI5NTQ0NmVhZDUwODQzODE0OTQ4NTdjMzAxNTQ5Y2ZjY2M4YzRiODU0ZjIwNDhmMDA0Yjc4OWQifQ';
    $hash2 = 'eyJpdiI6ImRBVWNKVTlJZVFmckk2T0c4cXNObFE9PSIsInZhbHVlIjoidElqcE5TMUFwVHZXeW12R3hKMFVFWlR0WmgxOFRBbW5cL2V3dUJ6VndsdktLYjVGR2JQQWpSUUNUWDBJbU5OQWEiLCJtYWMiOiI3MjM3ODNiMzc0NDJlNDVhYzFkOTBmMjhhOTk0MTUyM2FlNzM5ZGE4ODE3MTJlMDM5NWZiMzViZjM5OTA0MGRhIn0=';
    $dump = [
    'hash1' => $hash1,
    'hash2' => $hash2,
    'string1' => Crypt::decrypt($hash1),
    'string2' => Crypt::decrypt($hash2)
    ];
    return $dump;

崩溃的对象

hash1: "eyJpdiI6InJFNTFkdktpVU9cL1wvRTJPVk94SURiUT09IiwidmFsdWUiOiJIZVh4Y1NyUGpVcTVFVTNSbWdUNnJCUWRHSGZTcnFTQWJKa1h0Q1wvMEVtZnFuM3dDeFwvXC9hdUs4enFXXC94dEJ0cSIsIm1hYyI6IjFjNjZjODFjMjI5NTQ0NmVhZDUwODQzODE0OTQ4NTdjMzAxNTQ5Y2ZjY2M4YzRiODU0ZjIwNDhmMDA0Yjc4OWQifQ"
hash2: "eyJpdiI6ImRBVWNKVTlJZVFmckk2T0c4cXNObFE9PSIsInZhbHVlIjoidElqcE5TMUFwVHZXeW12R3hKMFVFWlR0WmgxOFRBbW5cL2V3dUJ6VndsdktLYjVGR2JQQWpSUUNUWDBJbU5OQWEiLCJtYWMiOiI3MjM3ODNiMzc0NDJlNDVhYzFkOTBmMjhhOTk0MTUyM2FlNzM5ZGE4ODE3MTJlMDM5NWZiMzViZjM5OTA0MGRhIn0="
string1: "admin03@y..sef...iman.com"
string2: "admin03@y..sef...iman.com"

为保护隐私,字符被用点号代替,但实际上它们是完全相同的。我唯一能想到的可能是某种字符集格式?

任何解决此问题的帮助都将不胜感激!

敬礼。


1
等等,如果解密后的哈希值相同,那问题是什么? - Matthew Brown
如果密钥不同,则加密值也将不同;而密钥不应始终相同,否则它会变得可预测且容易被破解。这就是整个重点。 - Mark Baker
@MarkBaker 抱歉,我对加密一般不太了解 - 我以为两种方式会给出相同的值。关键是这些值必须存储在数据库表中,但也要成为数据行的检索点,现在我必须想出另一种更可行的方法 :)。 - VitaCoco
你能发布你当前的查询吗?为什么不能使用不同的列选择值? - Matthew Brown
“SELECT * FROM users WHERE email = '#hashvalue' LIMIT 1” 是有效的,尽管使用 Laravel 的 Eloquent ORM。这是用于重置密码的,因此保证发送带有密码重置令牌的电子邮件到正确的电子邮件地址的唯一可行选项是将用户输入的电子邮件地址与“email”值进行匹配。我刚刚尝试使用了 bcrypt(),据我所知,它是单向加密,但结果仍然相同。 - VitaCoco
如果这是用于密码存储,你不想加密数据,而是要进行哈希处理。你应该使用bcrypt(),不是因为结果总是相同,而是因为它无法被反向解密。 - mfanto
1个回答

5
如果我理解你的问题,你想知道为什么即使输入和密钥相同,加密结果也会不同?
(你提到这些是哈希值,但Crypt :: encrypt()和decrypt()用于对称加密) Laravel Crypt默认使用CBC模式。这意味着每次加密时它都会生成一个随机IV,以确保输出始终不同。
如果不使用像CBC这样的模式,则会有泄漏信息的风险。如果我知道admin03@y..sef...iman.com始终加密为eyJpdiI6InJFNTFkdktpVU9cL1wvRTJPVk94SURiUT09IiwidmFsdWUiOiJIZVh4Y1NyUGpVcTVFVTNSbWdUNnJCUWRHSGZTcnFTQWJKa1h0Q1wvMEVtZnFuM3dDeFwvXC9hdUs4enFXXC94dEJ0cSIsIm1hYyI6IjFjNjZjODFjMjI5NTQ0NmVhZDUwODQzODE0OTQ4NTdjMzAxNTQ5Y2ZjY2M4YzRiODU0ZjIwNDhmMDA0Yjc4OWQifQ,那么即使我不知道你的加密密钥,我仍然知道有关您的消息的一些信息(例如发送给谁)。
你可以在这里看到一个很好的风险示例。
编辑:如果这是用于密码存储,则不应使用encrypt()和decrypt()。你应该使用bcrypt()或PBKDF2。否则,在假设受到攻击的情况下,攻击者可以轻松解密所有用户的密码。

1
Laravel的Hash门面有一个方便的make方法,所以当您想为用户生成密码时,只需调用Hash::make($string)即可。这也是内置的Auth类用于在提交时检查密码的方法。 - kalatabe

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接