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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/29518652/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-14 11:19:16  来源:igfitidea点击:

Laravel 5 Encryption - Different values for same string given?

phpmysqllaravelencryptionlaravel-5

提问by VitaCoco

I'm using Laravel 5, and for a project, for which one of the tenants is that emails stored in the system must be encrypted. I am using Laravel 5's Crypt::facade, and the relevant encrypt()and decrypt()methods.

我正在使用 Laravel 5,对于一个项目,其中一个租户是必须加密存储在系统中的电子邮件。我正在使用 Laravel 5 的Crypt::外观,以及相关的encrypt()decrypt()方法。

The problem lies in that the encrypted value seems to differ, even if given the same string. At first I thought it could be to do with VARCHARfield max lengths, however both the hash values come back under the 255 length set on the field.

问题在于加密值似乎不同,即使给出相同的字符串。起初我认为这可能与VARCHAR字段最大长度有关,但是两个哈希值都回到了字段上设置的 255 长度之下。

Take for example, this dump;

以这个转储为例;

PHP

PHP

    $hash1 = 'eyJpdiI6InJFNTFkdktpVU9cL1wvRTJPVk94SURiUT09IiwidmFsdWUiOiJIZVh4Y1NyUGpVcTVFVTNSbWdUNnJCUWRHSGZTcnFTQWJKa1h0Q1wvMEVtZnFuM3dDeFwvXC9hdUs4enFXXC94dEJ0cSIsIm1hYyI6IjFjNjZjODFjMjI5NTQ0NmVhZDUwODQzODE0OTQ4NTdjMzAxNTQ5Y2ZjY2M4YzRiODU0ZjIwNDhmMDA0Yjc4OWQifQ';
    $hash2 = 'eyJpdiI6ImRBVWNKVTlJZVFmckk2T0c4cXNObFE9PSIsInZhbHVlIjoidElqcE5TMUFwVHZXeW12R3hKMFVFWlR0WmgxOFRBbW5cL2V3dUJ6VndsdktLYjVGR2JQQWpSUUNUWDBJbU5OQWEiLCJtYWMiOiI3MjM3ODNiMzc0NDJlNDVhYzFkOTBmMjhhOTk0MTUyM2FlNzM5ZGE4ODE3MTJlMDM5NWZiMzViZjM5OTA0MGRhIn0=';
    $dump = [
    'hash1' => $hash1,
    'hash2' => $hash2,
    'string1' => Crypt::decrypt($hash1),
    'string2' => Crypt::decrypt($hash2)
    ];
    return $dump;

Dumped Object

转储对象

hash1: "eyJpdiI6InJFNTFkdktpVU9cL1wvRTJPVk94SURiUT09IiwidmFsdWUiOiJIZVh4Y1NyUGpVcTVFVTNSbWdUNnJCUWRHSGZTcnFTQWJKa1h0Q1wvMEVtZnFuM3dDeFwvXC9hdUs4enFXXC94dEJ0cSIsIm1hYyI6IjFjNjZjODFjMjI5NTQ0NmVhZDUwODQzODE0OTQ4NTdjMzAxNTQ5Y2ZjY2M4YzRiODU0ZjIwNDhmMDA0Yjc4OWQifQ"
hash2: "eyJpdiI6ImRBVWNKVTlJZVFmckk2T0c4cXNObFE9PSIsInZhbHVlIjoidElqcE5TMUFwVHZXeW12R3hKMFVFWlR0WmgxOFRBbW5cL2V3dUJ6VndsdktLYjVGR2JQQWpSUUNUWDBJbU5OQWEiLCJtYWMiOiI3MjM3ODNiMzc0NDJlNDVhYzFkOTBmMjhhOTk0MTUyM2FlNzM5ZGE4ODE3MTJlMDM5NWZiMzViZjM5OTA0MGRhIn0="
string1: "[email protected]"
string2: "[email protected]"

Dots are inputted in place of characters for privacy, but they are exactly the same. The only other thing I can possibly think about is maybe some kind of charset formatting?

输入点代替字符以保护隐私,但它们完全相同。我唯一能想到的可能是某种字符集格式?

Any help resolving this would be greatly appreciated!

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

Regards.

问候。

回答by mfanto

If I understand your question, it's why does the encrypted results differ, even with the same input and the same key?

如果我理解您的问题,这就是为什么即使输入相同且密钥相同,加密结果也会不同?

(You mention these being hashes, but Crypt::encrypt() and decrypt() are for symmetric encryption)

(您提到这些是散列,但 Crypt::encrypt() 和decrypt() 用于对称加密)

Laravel Crypt uses CBC mode by default. That means it generates a random IV every time you encrypt something, to ensure the output is always different.

Laravel Crypt 默认使用 CBC 模式。这意味着每次加密时它都会生成一个随机 IV,以确保输出始终不同。

Without using a mode like CBC, you risk leaking information. If I know that [email protected]always encrypts to eyJpdiI6InJFNTFkdktpVU9cL1wvRTJPVk94SURiUT09IiwidmFsdWUiOiJIZVh4Y1NyUGpVcTVFVTNSbWdUNnJCUWRHSGZTcnFTQWJKa1h0Q1wvMEVtZnFuM3dDeFwvXC9hdUs4enFXXC94dEJ0cSIsIm1hYyI6IjFjNjZjODFjMjI5NTQ0NmVhZDUwODQzODE0OTQ4NTdjMzAxNTQ5Y2ZjY2M4YzRiODU0ZjIwNDhmMDA0Yjc4OWQifQ, then even without knowing your encryption key, I still know somethingabout your messages (who it's being sent to, for example).

如果不使用 CBC 之类的模式,您就有泄露信息的风险。如果我知道,[email protected]总是要进行加密eyJpdiI6InJFNTFkdktpVU9cL1wvRTJPVk94SURiUT09IiwidmFsdWUiOiJIZVh4Y1NyUGpVcTVFVTNSbWdUNnJCUWRHSGZTcnFTQWJKa1h0Q1wvMEVtZnFuM3dDeFwvXC9hdUs4enFXXC94dEJ0cSIsIm1hYyI6IjFjNjZjODFjMjI5NTQ0NmVhZDUwODQzODE0OTQ4NTdjMzAxNTQ5Y2ZjY2M4YzRiODU0ZjIwNDhmMDA0Yjc4OWQifQ,那么即使不知道你的加密密钥,我还是知道一些关于你的消息(谁它被送往,例如)。

You can see a great example of the risk here.

您可以在这里看到一个很好的风险示例。

Edit: If this is for password storage, you should not be using encrypt() and decrypt(). You should use bcrypt() or PBKDF2. Otherwise, assuming a compromise, an attacker could just decrypt all your users passwords.

编辑:如果这是用于密码存储,则不应使用 encrypt() 和decrypt()。您应该使用 bcrypt() 或 PBKDF2。否则,假设有妥协,攻击者可以解密您所有的用户密码。