sha256 / salt密码密钥存储

时间:2015-07-28 15:15:53

标签: php mysql salt sha256 password-hash

我已经创建了一个如下处理的注册表单:

function register_user() {
   global $conn;
   $name      = sanitize($_POST['name']);
   $email     = sanitize($_POST['email']);
   $password = sanitize($_POST['password']);
   $salt      = bin2hex(mcrypt_create_iv(32, MCRYPT_DEV_URANDOM));

   $saltedPW = $password . $salt;
   $hashedPW = hash('sha256', $saltedPW);

   mysqli_query($conn, "INSERT INTO users (name, email, password, salt) VALUES ('$name', '$email', '$hashedPW', '$salt')");

然后按如下方式处理登录表单:

    function login($email, $password) {
    global $conn;
    $user_id = user_id_from_username($email);
    $query   = mysqli_query($conn, "SELECT salt FROM users WHERE email = '$email'");
    $row1    = mysqli_fetch_assoc($query);
    $salt    = $row1['salt'];

    $saltedPW = $password . $salt;
    $hashedPW = hash('sha256', $saltedPW);

    $result = mysqli_query($conn, "SELECT COUNT(user_id) FROM users WHERE email = '$email' AND password = '$hashedPW'");
    $row     = mysqli_fetch_row($result);

    return ($row[0] == 1) ? $user_id : false;
}

用户表的结构如下: 用户身份;名称;电子邮件;密码; salt(用于密码恢复的其他列,管理员权限等)。在向我公司的IT合规部门提交了详细信息之后,有PHP经验的人(毫无疑问,超过我的)已声明我无法在系统中存储加密密钥 - 如果有人拿到文件他们可以解密密码。我的问题是 - 这是正确的吗?我的流程有缺陷吗?我所进行的所有研究表明,随机盐的SHA256哈希是最好的方法之一。

2 个答案:

答案 0 :(得分:5)

I can't store the key for the encryption in the system

You haven't. You're hashing, you're not encrypting. salt !== key

if someone got the file they could decrypt the password

No. Nothing is encrypted, so there's nothing to decrypt. They'd get only the resulting hash, which they'd still have to brute force.

Is my process flawed?

Yes, but not because of their comments. It's flawed because you should never use SHA or MD5 or similar for passwords. They're designed to be fast, which is not what you want. You want something that intentionally takes a hunk of CPU, as to make brute force attacks untimely. This is exactly what the password_hash() function is for. Use it.

答案 1 :(得分:2)

请勿使用sha256,md5等进行密码散列。我认为你应该使用BCrypt进行密码散列。这是目前最强大的密码哈希算法。 password_hash()password_verify()用于哈希和验证BCrypt的密码。 PHP 5.5.0或更高版本使用BCrypt作为password_hash()的默认算法。不要使用自己的盐。让password_hash()为你做。