使用sha1和salt存储密码

时间:2012-10-29 02:38:01

标签: php hash mysqli sha1 salt

我在php中完成了一个简单的注册脚本,我只是很好奇,如果我这样做的方式足够安全,可以存储用户密码。我正在生成一个32位随机盐并将其附加到sha1哈希密码。

//create new validator object
    $validator = new data_validation();
    //validate user input
    $firstName = $validator->validate_fname($firstName); //is the first name a string?
    $lastName = $validator->validate_lname($lastName); // is the last name a string?
    $username = $validator->validate_username($username); // is the username a string?
    $email = $validator->validate_email($email); //is the email in valid format?

    //make sure there isn't duplicate emails
    $valQuery = $link->query("SELECT email FROM users WHERE email = '" .$email. "'");

    if ($valQuery->num_rows == 1) {
        echo "An email is already registered with that address";
        return false;
    }

    // generate a random salt for converting passwords into sha1
    $salt = $link->real_escape_string(bin2hex(mcrypt_create_iv(32, MCRYPT_DEV_URANDOM)));
    $saltedPW =  $password . $salt;
    $hashedPW = sha1($saltedPW);

    mysqli_connect($db_host, $db_user, $db_pass) OR DIE (mysqli_error());
    // select the db
    mysqli_select_db ($link, $db_name) OR DIE ("Unable to select db".mysqli_error($db_name));

     // our sql query
    $sql = "INSERT INTO users (first_name, last_name, username, email, password, salt) VALUES ('$firstName', '$lastName', '$username', '$email', '$hashedPW', '$salt');";

    //save the updated information to the database          
    $result = mysqli_query($link, $sql) or die("Error in Query: " . mysqli_error($link));

    if (!mysqli_error($link)) 
    {
        $row = mysqli_fetch_assoc($result);
        $_SESSION['user_id'] = $row['user_id'];
        $_SESSION['loggedin'] = TRUE;
        header("Location: ../home");
    }

另外,我正在使用程序和oop php的组合。其中大部分都是在过程中完成的,但是有一些oop类,比如你在上面的脚本中看到的验证类。这是否会导致使用这两种样式的性能问题?

2 个答案:

答案 0 :(得分:6)

没有。停止你正在做的事情,阅读How to securely hash passwords,然后阅读Secure hash and salt for PHP passwords

最重要的是:

  
      
  • 尽可能使用scrypt; bcrypt,如果你不能。
  •   
  • 如果您不能使用bcrypt或scrypt,请使用PBKDF2。
  •   

有关PBKDF2,bcrypt和scrypt的比较,请参阅this answer

另请参阅经常链接的文章How To Safely Store A Password

  

[MD5,SHA1,SHA256,SHA512,SHA-3等]都是通用散列函数,用于在尽可能短的时间内计算大量数据的摘要。这意味着它们非常适合确保数据的完整性和存储密码的完全垃圾。

PHPass可能是在PHP中进行bcrypt散列的最简单方法。如果您愿意,也可以使用do it the hard wayCRYPT_BLOWFISH crypt function,但请注意,有很多方法可以解决问题,界面相当神秘(就像您指定的那样)盐值)。

答案 1 :(得分:2)

在程序和OO之间切换本身不会影响性能。加载和实例化类的开销是可以忽略的。但是,管理增长的非OO代码库可能是一项不可忽视的任务 - 尤其是在全局命名空间中处理所有内容。

在插入(盐)中添加其他字段也不会影响任何内容。使用salt不会增加sha1算法的开销,方法是将其添加到密码的末尾。

我对你如何选择生成随机盐有点困惑,但它看起来也不是很系统化。