我是否正确使用了 PHP 的 crypt() 函数?

2022-08-30 23:14:10

我一直在使用PHP作为在我的数据库中存储和验证密码的一种方式。我将哈希用于其他事情,但用于密码。文档不是那么好,似乎有很多争论。我正在使用河豚和两种盐来加密密码并将其存储在数据库中。之前我会存储盐和加密的密码(如盐渍哈希),但意识到它是多余的,因为盐是加密密码字符串的一部分。crypt()crypt()

我对彩虹表攻击的工作方式有点困惑,无论如何,从安全的角度来看,这看起来是否正确。我使用第二个盐来附加到密码以增加短密码的熵,可能有点过分,但为什么不呢?crypt()

function crypt_password($password) {
if ($password) {
    //find the longest valid salt allowed by server
    $max_salt = CRYPT_SALT_LENGTH;

    //blowfish hashing with a salt as follows: "$2a$", a two digit cost parameter, "$", and 22 base 64
    $blowfish = '$2a$10$';

    //get the longest salt, could set to 22 crypt ignores extra data
    $salt = get_salt ( $max_salt );

    //get a second salt to strengthen password
    $salt2 = get_salt ( 30 ); //set to whatever


    //append salt2 data to the password, and crypt using salt, results in a 60 char output
    $crypt_pass = crypt ( $password . $salt2, $blowfish . $salt );

    //insert crypt pass along with salt2 into database.
    $sql = "insert into database....";

    return true;
    }
}  


function get_salt($length) {
$options = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789./';

$salt = '';

for($i = 0; $i <= $length; $i ++) {
    $options = str_shuffle ( $options );
    $salt .= $options [rand ( 0, 63 )];
}
return $salt;
}

function verify_password($input_password)
{
if($input_password)
{
    //get stored crypt pass,and salt2 from the database
    $stored_password = 'somethingfromdatabase';
    $stored_salt2 = 'somethingelsefromdatabase';

    //compare the crypt of input+stored_salt2 to the stored crypt password
    if (crypt($input_password . $stored_salt2, $stored_password) == $stored_password) {
        //authenticated
        return true;
    }
    else return false;
}
else return false;
}

答案 1

你真的应该看看PHPASS:http://www.openwall.com/phpass/ 这是一个使用crypt()的密码哈希框架,用于Wordpress和phpBB等项目。

这个网站上还有一篇关于密码散列,盐渍和使用crypt()拉伸的优秀文章:http://www.openwall.com/articles/PHP-Users-Passwords

更新:目前有PHPASS库的替代方案。在下一个版本的PHP中,有用于散列和验证密码的特殊函数(使用bcrypt):http://www.php.net/manual/en/ref.password.php。有一个兼容性库为 PHP 5.3.7+ 实现以下函数:https://github.com/ircmaxell/password_compat


答案 2

你的使用是好的。 是它被设计使用的方式。crypt()crypt($input, $stored) == $stored

您的函数不是很好,因为它使用的是经常较差的函数。您应该考虑使用更强的随机函数,例如 ,get_salt()rand()openssl_random_pseudo_bytes()


推荐