3

我有一个用 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 类,例如您在上面的脚本中看到的验证类。这会导致使用这两种样式的任何性能问题吗?

4

2 回答 2

6

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

最重要的是:

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

有关 PBKDF2、bcrypt 和 scrypt 的比较,请参阅此答案

另请参阅经常链接的文章如何安全地存储密码

[MD5, SHA1, SHA256, SHA512, SHA-3, etc] 都是通用哈希函数,旨在在尽可能短的时间内计算出海量数据的摘要。这意味着它们非常适合确保数据的完整性,而存储密码则完全是垃圾。

PHPass可能是在 PHP 中进行 bcrypt 散列的最简单方法。如果需要,您也可以使用crypt 函数以艰难的方式完成此操作,但请注意,有很多方法会出错,并且界面相当晦涩(就像您指定盐值的方式一样)。CRYPT_BLOWFISH

于 2012-10-29T02:42:39.243 回答
2

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

在插入中添加一个额外的字段(盐)也不会影响任何事情。使用盐不会通过将 sha1 算法附加到密码的末尾来增加开销。

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

于 2012-10-29T02:41:08.620 回答