php 中没有电子邮件的冲突哈希

No collision hash of email in php

这个问题之前有人问过,但是很多帖子都太老了。

我需要对电子邮件地址进行哈希处理以存储在我的数据库中。稍后我需要匹配一个哈希值,因此对于每封唯一的电子邮件,哈希值每次都必须相同。有相同哈希值的风险吗?与 say md5() 或 hash() 发生冲突?这些天(2021)推荐的方式是什么

提前致谢

很简单。 password_hash() 是 md5() 的替代品。 但是你在这里谈论的是散列电子邮件。电子邮箱与密码不同。

作为管理员,您无需知道用户密码即可授予用户访问权限。但是,如果您想发送时事通讯、注册确认,甚至提供通过电子邮件找回丢失的用户帐户访问权限的选项,您将需要知道用户电子邮件。上面的哈希选项都不会帮助你。因为上面的选项会破坏原始数据并给你留下碎片。

在任何情况下,password_hash() 都是 60 个字符,而 md5() 是 32 个字符。所以 password_hash() 是最安全的选择,而 md5() 早已过时,不应使用。密码冲突不是您应该担心的事情。因为用户可以拥有相同的密码甚至相同的哈希数据。但是由于数据属于不同的账户,如果没有正确的用户名,哈希对用户登录没有用。

所以现在一切都归结为电子邮件。您可以使用这种简单的加密和解密来实现。在这种情况下,由于数据未被破坏并被保留。这意味着不会发生冲突,特别是考虑到每个用户都应该有不同的电子邮件。但是即使数据完全一样,每次哈希的结果还是会不一样。所以这个选项不会出错。

function enc($data, $key, $mode=0){
    $cipher = "aes-256-gcm";
    if(in_array($cipher, openssl_get_cipher_methods())){
        if(!$mode){ // encrypt
            $ivlen = openssl_cipher_iv_length($cipher);
            $iv = openssl_random_pseudo_bytes($ivlen);
            $data = openssl_encrypt($data, $cipher, $key, $options=0, $iv, $tag);
            $data = base64_encode($data.'::'.$iv.'::'.$tag);
        }else{      // decrypt
            list($data, $iv, $tag) = explode('::', base64_decode($data), 3);
            $data = openssl_decrypt($data, $cipher, $key, $options=0, $iv, $tag);
        }
    }
    return $data;
}
  • 加密数据:enc('DATA','KEY');(其中 KEY 可能是用户密码) => RETURNS: ENC_KEY
  • 解密数据:enc('ENC_KEY','KEY',1);(其中 KEY 可能是用户密码) => RETURNS: DATA

从 PHP 7.2 开始,您将像这样使用 Argon2:

password_hash('your_value', PASSWORD_ARGON2I);

PHP 7.3自带改进算法:

password_hash('your_value', PASSWORD_ARGON2ID);

要将值与哈希值进行比较,您可以像这样使用 password_verify

if (password_verify($user_value, $stored_hash)) {
    // valid
}

这通常是为了检查散列密码,但电子邮件地址也可以用同样的方式处理(例如出于数据保护原因)。

Argon2 algorithm is explained in Wikipedia, the Installation is described on php.net.