这是在 php 中从 mcrypt 升级到 LibSodium 的正确过程吗?

问题描述

我正在将我的服务器从 PHP 5.4 升级到 7.4,并且准备将用户登录系统从 mcrypt 转换为(可能)使用 Argon2 或 Bcrypt 的 Halite 或 Libsodium

我一直在研究,仍然有办法解决这个问题,但想在这里检查一下,看看 a) 到目前为止我对升级过程有正确的想法,以及 b)我正在遵循最佳实践前进。我想知道...

  1. 使用 Argon2 的 Halite 或 Libsodium 是可行的方法,还是 Bcrypt 很好,它们在未来 5 到 10 年都能合理地适应未来吗?

  2. 现代密码认证的总体思路是否与旧方式相同——密码被转换并存储为散列,然后在登录期间输入的密码被散列并与存储的散列进行比较(使用此方法的现代版本使用更安全的方法来创建哈希)?或者这个过程是否意味着完全不同的处理?据我所知,是一样的。

  3. 如果我在 2) 中有正确的想法,升级时以下哪项是正确的(甚至可能的)方法

a) 使用像 Libsodium 这样的库通过下面的 create_password_hash() 获取在我的旧系统中创建的密码哈希,并将其转换为可以存储在新系统中的 Libsodium 哈希

b) 将当前密码哈希下载到我的本地机器上,使用 mcrypt 来解密原始密码(这甚至可能吗?我猜不,因为 create_password_hash () 不是单向哈希函数加上暴露原始密码与最佳实践相反),然后使用 Libsodium 从原始密码创建新密码哈希,并将这些新哈希上传数据库中以供新登录系统使用

c) 没有办法解决 - 用户只需在新系统中手动重置密码?

d) 另一种我不知道的方式

旧系统:

用户注册创建的加密密码如下(以散列形式存储):

define('PASSHASH_PBKDF2_ITERS',500);
define('PASSHASH_SALT_BYTES',32);
define('PASSHASH_HASH_BYTES',32);

function create_password_hash($password)
{
    if($password === "")
        trigger_error('Blank password',E_USER_WARNING);
    $key = get_secret_key();
    $salt = bin2hex(mcrypt_create_iv(PASSHASH_SALT_BYTES,MCRYPT_DEV_URANDOM));
    $hash = bin2hex(
        pbkdf2("sha256",$key . $password,$salt,PASSHASH_PBKDF2_ITERS,PASSHASH_HASH_BYTES)
    );    
    return PASSHASH_PBKDF2_ITERS . ":" . $salt . ":" . $hash;
}

function pbkdf2($algorithm,$password,$count,$key_length)
 {
     $algorithm = strtolower($algorithm);
     if(!in_array($algorithm,hash_algos(),true))
         die('PBKDF2 ERROR: Invalid hash algorithm.');
     if($count <= 0 || $key_length <= 0)
         die('PBKDF2 ERROR: Invalid parameters.');
 
     // number of blocks = ceil(key length / hash length)
     $hash_length = strlen(hash($algorithm,"",true));
     $block_count = $key_length / $hash_length;
     if($key_length % $hash_length != 0)
         $block_count += 1;
 
     $output = "";
     for($i = 1; $i <= $block_count; $i++) {
         //$i encoded as 4 bytes,big endian.
         $last = $salt . pack("N",$i);
         // first iteration
         $last = $xorsum = hash_hmac($algorithm,$last,true);
         // perform the other $count - 1 iterations
         for ($j = 1; $j < $count; $j++) {
             $xorsum ^= ($last = hash_hmac($algorithm,true));
         }
         $output .= $xorsum;
     }
 
     return substr($output,$key_length);
 }

登录过程中,我验证了用户密码如下:

function authenticate_password($password,$correctHash)
{
    $params = explode(":",$correctHash);
    if(count($params) != 3)
        return false;
    $iters = (int)$params[0];
    $salt = $params[1];
    $hash = $params[2];
    $key = get_secret_key();    
    $testHash = bin2hex(
        pbkdf2("sha256",$iters,PASSHASH_HASH_BYTES)
    );      
    return $testHash === $hash;
}

谢谢!

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...