忘記 MD5 Sha1 吧 從現在開始使用 Bcrypt 和 Argon2i 吧

hallo_monde發表於2018-05-06
  • 昨天突然發現身邊還有人在使用md5進行加密,明明連php官網都不建議使用md5

  • 所以建議大家儘快拋棄 md5 和 sha1 這些不安全的演算法

  • php在5.5版本以後已經為我們提供了非常安全的加密函式 bcrypt

    • 使用函式 password_hash 生成基於Bcrypt演算法的hash值
      使用的具體如下
    $password = filter_input(INPUT_POST, 'password');
    $password = password_hash($password, PASSWORD_DEFAULT, ['cost' => 12]);
    
    password_hash 的第二個選項就是選擇使用的加密方法,預設選用的就是Bcrypt加密
    第三個引數是工作因子cost,和 salt,不填就為預設
    password_verify ($password, $hash)
    $password為明文密碼,$hash為經過 password_hash函式雜湊過後的值
    相等會返回true,不相等會返回true
    
    • password_needs_rehash 函式檢測指定的hash值是否實現了提供的演算法和選項。 如果沒有,需要重新生成hash值
  • 下面有一個完整的登入的例子可以給大家演示一下

<?php

session_start();

try {
    $email = filter_input(INPUT_POST, 'email');
    $password = filter_input(INPUT_POST, 'password');

    $user = User::findByEmail($email);

    if (password_verify($password, $user->password) === false) {
        throw new Exception('密碼錯誤');
    }

    $currentHashAlgorithm = PASSWORD_DEFAULT;
    $currentHashOptions = ['cost' => 15];

    $passwordNeedRehash = password_needs_rehash(
        $user->password,
        $currentHashAlgorithm,
        $currentHashOptions
    );

    if ($passwordNeedRehash === true) {
        $password = password_hash(
            $password,
            $currentHashAlgorithm,
            $currentHashOptions
        );

        $user->save();
    }

    $_SESSION['user_logged_in'] = 'yes';
    $_SESSION['user_email'] = $email;

    header('HTTP/1.1 302 Redirect');
    header('Location:/index.php');

} catch (Exception $e) {
    header('HTTP/1.1 401 Unauthorized');
    echo $e->getMessage();
}
  • php7.2 提供了一個比 Bcrypt 更加安全的演算法 Argon2i

    • 使用的方法也很簡單 把 password_hash 的第二個引數改成PASSWORD_ARGON2I 即可
    • 當然它也有第三個選項 裡面有三個引數
      • memory_cost (integer) - 計算 Argon2 雜湊時的最大記憶體
      • time_cost (integer) - 計算 Argon2 雜湊時最多的時間
      • threads (integer) - 計算 Argon2 雜湊時最多的執行緒數
  • 下面我們來比較一下 md5 sha1 bcrypt argon2i 演算法

    bcrypt 和 argon2i 使用預設配置

<?php

$password=123456;

var_dump(md5($password));
var_dump(sha1($password));
var_dump($password = password_hash($password, PASSWORD_DEFAULT));
var_dump($password = password_hash($password, PASSWORD_ARGON2I));

結果

[root@JD ~]# php hash.php 
string(32) "e10adc3949ba59abbe56e057f20f883e"
string(40) "7c4a8d09ca3762af61e59520943dc26494f8941b"
string(60) "$2y$10$5AnWGMjHEg3cDTsH5miUTuU7wY7OpERSIfMwxZzM.mWiNwj4oOps6"
string(95) "$argon2i$v=19$m=1024,t=2,p=2$d1JQR3Z2dDdtTFZURGU2RQ$xcac0lc1Olp75uA+Zv6ICIFFLAJpUKJ0rrZKRvribaA"
[root@JD ~]# php hash.php 
string(32) "e10adc3949ba59abbe56e057f20f883e"
string(40) "7c4a8d09ca3762af61e59520943dc26494f8941b"
string(60) "$2y$10$zQlRfj.T/Qa9VkwiHBeN7.s1AUixlDtouLBkzX2jf9e3pYLgwPgGq"
string(95) "$argon2i$v=19$m=1024,t=2,p=2$WlNkU2d4dXhsSFJpbVhQYQ$t1jh8GuzRrCF+neeBfoXeZA6/Jxu2EudAg1WdbT3JJk"

顯然易見 我們可以發現 bcrypt 和 argon2i 更加安全
如果有不相信的同學 可以到一些解密網站 如 cmd5 等去嘗試解密 你會發現 md5 和 sha1 是真的非常容易被破解

本作品採用《CC 協議》,轉載必須註明作者和本文連結

相關文章