duandang9434 2015-05-08 04:08
浏览 54
已采纳

如何在登录时使用salt和hash?

I want to use salt and hash to create security login. I try to follow this tutorial and write own code but it always return false. Here is my code:

require_once 'application/third_party/Secure-Login/classes/Hashing.php';
require_once 'application/third_party/Secure-Login/classes/Salt.php';
$password = Hashing::create_hash('123456', Salt::random(12));
$old = '$2a$10$zuzycDw3Ack2cCoL3ds1sudJ2WioZ87.75ErLZVcZyh4d1hS2rHFu';

if (Hashing::validate($password, $old, Salt::random(12))) {
    echo true;
} else {
    echo false;
}

And two classes I included:

<?php

class Hashing {

    function __construct() {}

    /**
    * @param string $pass The user submitted password
    * @param string $hashed_pass The hashed password pulled from the database
    * @param string $salt The salt pulled from the database
    * @param string $hash_method The hashing method used to generate the hashed password
    */
    static function validate($pass, $hashed_pass, $salt, $hash_method = 'sha1') {
        if (function_exists('hash') && in_array($hash_method, hash_algos())) {
            return ($hashed_pass === hash($hash_method, $salt . $pass));
        }
        return ($hashed_pass === sha1($salt . $pass));
    }

    /**
     * Generates a secure, pseudo-random password with a safe fallback.
     */
    static function pseudo_rand($length) {
        if (function_exists('openssl_random_pseudo_bytes')) {
            $is_strong = false;
            $rand = openssl_random_pseudo_bytes($length, $is_strong);
            if ($is_strong === true) {
                return $rand;
            }
        }
        $rand = '';
        $sha = '';
        for ($i = 0; $i < $length; $i++) {
            $sha = hash('sha256', $sha . mt_rand());
            $chr = mt_rand(0, 62);
            $rand .= chr(hexdec($sha[$chr] . $sha[$chr + 1]));
        }
        return $rand;
    }

    /**
     * Creates a very secure hash. Uses blowfish by default with a fallback on SHA512.
     */
    static function create_hash($string, $salt = '', $hash_method = 'sha1', $stretch_cost = 10) {
    $salt = Hashing::pseudo_rand(128);
    $salt = substr(str_replace('+', '.', base64_encode($salt)), 0, 22);
    if (function_exists('hash') && in_array($hash_method, hash_algos())) {
            return crypt($string, '$2a$' . $stretch_cost . '$' . $salt);
    }
    return Hashing::_create_hash($string, $salt);
    }

    /**
     * Fall-back SHA512 hashing algorithm with stretching.
     */
    static function _create_hash($password, $salt) {
        $hash = '';
        for ($i = 0; $i < 20000; $i++) {
            $hash = hash('sha512', $hash . $salt . $password);
        }
        return $hash;
    }

}

<?php

class Salt {

    public static function random($len = 8) {
    $chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789`~!@#$%^&*()-=_+';
    $l = strlen($chars) - 1;
    $str = '';
    for ($i = 0; $i < $len; ++$i) {
            $str .= $chars[rand(0, $l)];
    }
    return $str;
    }

}

Please check help me! I don't know where is wrong and how it works. Thank so much!

  • 写回答

3条回答 默认 最新

  • doudeng9425 2015-05-08 11:11
    关注

    There are many problems with your code, so i strongly suggest to use the functions password_hash() and password_verify() to do the hashing.

    Because you said that you want to understand how it works, here some tips:

    static function create_hash($string, $salt = '', $hash_method = 'sha1', $stretch_cost = 10) {
      $salt = Hashing::pseudo_rand(128);
      $salt = substr(str_replace('+', '.', base64_encode($salt)), 0, 22);
      if (function_exists('hash') && in_array($hash_method, hash_algos())) {
        return crypt($string, '$2a$' . $stretch_cost . '$' . $salt);
      }
      return Hashing::_create_hash($string, $salt);
    }
    

    This method first tries to use crypt() which is good, because it generates a BCrypt hash. The cost parameter will fail if it is smaller than 10, and the salt can be generated unsafe, and it uses ways too much entropy from the pool. Then it checks whether the hash() functions exists but this function is not at all made to hash passwords and has nothing to do with crypt().

    Later for verification you do not use crypt(), instead you check with the hash() function, this is a different algorithm as before. Then the salt cannot be choosen freely to verify a password, instead you need the same salt that was used to generate the hash, the crypt() function actually did include this salt in the hash-value.

    static function validate($pass, $hashed_pass, $salt, $hash_method = 'sha1') {
      if (function_exists('hash') && in_array($hash_method, hash_algos())) {
        return ($hashed_pass === hash($hash_method, $salt . $pass));
      }
      return ($hashed_pass === sha1($salt . $pass));
    }
    

    If you want to learn a bit more about password hashing, i would invite you to read my tutorial about secure password storing.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(2条)

报告相同问题?

悬赏问题

  • ¥15 C#算法问题, 不知道怎么处理这个数据的转换
  • ¥15 YoloV5 第三方库的版本对照问题
  • ¥15 请完成下列相关问题!
  • ¥15 drone 推送镜像时候 purge: true 推送完毕后没有删除对应的镜像,手动拷贝到服务器执行结果正确在样才能让指令自动执行成功删除对应镜像,如何解决?
  • ¥15 求daily translation(DT)偏差订正方法的代码
  • ¥15 js调用html页面需要隐藏某个按钮
  • ¥15 ads仿真结果在圆图上是怎么读数的
  • ¥20 Cotex M3的调试和程序执行方式是什么样的?
  • ¥20 java项目连接sqlserver时报ssl相关错误
  • ¥15 一道python难题3