繁体   English   中英

如何使用PHP中的Blowfish创建和存储密码哈希

[英]How to create and store password hashes with Blowfish in PHP

1)如何使用crypt()创建安全的Blowfish哈希密码?

$hash = crypt('somePassword', '$2a$07$nGYCCmhrzjrgdcxjH$');

1a)“$ 2a”的意义是什么? 它只是表明应该使用Blowfish算法吗?
1b)“07美元”有什么意义? 更高的值意味着更安全的哈希吗?
1c)“$ nGYCCmhrzjrgdcxjH $”有什么意义? 这是将要使用的盐吗? 这应该随机生成吗? 硬编码?

2)你如何存储河豚的哈希?

echo $hash;
//Output: $2a$07$nGYCCmhrzjrgdcxjH$$$$.xLJMTJxaRa12DnhpAJmKQw.NXXZHgyq

2a)这应该存储在数据库中的哪一部分?
2b)列应该使用什么数据类型(MySQL)?

3)如何验证登录尝试?

你应该存储crypt的整个输出,将它拆分起来并不是很重要,因为你需要为你在任何情况下散列的每个密码生成一个新的盐。 使用Matt提到的固定隐藏盐是错误的 - 每个哈希值的盐应该是不同的。

有关更多信息,请参阅http://www.openwall.com/articles/PHP-Users-Passwords - 我建议使用phpass库,因为它处理为您生成随机盐,与crypt()不同。

1a)加密强度 - 要求在4​​..31范围内。 http://php.net/manual/en/function.crypt.php

1b)见1a

1c)见1a。 'salt'不应该是随机的,否则你将无法为给定的输入重新生成相同的哈希值 - 参见3。

2a)严格地说,除了哈希之外的所有东西(如果数据库被泄露)。 此外,将您的salt存储在Web服务器的文档根目录下无法访问的文件中并包含它。 尽可能使用最严格的权限设置它; 理想情况下只读取Web主机服务(例如apache),没有写入或执行权限。 严格来说,取决于你希望如何防御黑客。 不储存盐只会让生活变得更加困难; 他们仍然必须将数据输入到算法中 - 但为什么要让它更容易?

2b)VARCHAR(32)对于河豚来说应该没问题,如果没有存储哈希值的话

3)假设您已经运行了正确的注入防护代码等。 所以请不要盲目地复制下面的内容 (理想情况下使用PDO而不是mysql扩展)。 下面是特定于河豚,SHA-256和SHA-512,它们都在哈希中返回盐。 需要修改其他算法......

//store this in another file outside web directory and include it
$salt = '$2a$07$somevalidbutrandomchars$'

...

//combine username + password to give algorithm more chars to work with
$password_hash = crypt($valid_username . $valid_password, $salt)

//Anything less than 13 chars is a failure (see manual)
if (strlen($password_hash) < 13 || $password_hash == $salt)
then die('Invalid blowfish result');

//Drop the salt from beginning of the hash result. 
//Note, irrespective of number of chars provided, algorithm will always 
//use the number defined in constant CRYPT_SALT_LENGTH
$trimmed_password_hash = substring($password_hash, CRYPT_SALT_LENGTH);
mysql_query("INSERT INTO `users` (username,p assword_hash) VALUES '$valid_username', '$trimmed_password_hash'");

...

$dbRes = mysql_query("SELECT password_hash FROM `users` WHERE username = '$user_input_username' LIMIT 1");
//re-apply salt to output of database and re-run algorithm testing for match
if (substring($salt, CRYPT_SALT_LENGTH) . mysql_result($dbRes, 0, 'password_hash') ) ===
        crypt($user_input_username . $user_input_password, $salt) ) {
    //... do stuff for validated user
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM