我时不时听到“使用bcrypt在PHP中使用密码,bcrypt规则存储密码”的建议。
但是bcrypt
是什么? PHP不提供任何此类功能,维基百科对文件加密实用程序不屑一顾,而Web搜索仅显示了几种以不同语言实现的Blowfish实现。 现在Blowfish也可以通过mcrypt
在PHP中使用,但这对存储密码有何帮助? 河豚是一种通用密码,它有两种工作方式。 如果可以加密,则可以解密。 密码需要单向散列功能。
有什么解释?
#1楼
编辑:2013.01.15-如果您的服务器支持它,请改用martinstoeckli的解决方案 。
每个人都想使事情变得更复杂。 crypt()函数完成大部分工作。
function blowfishCrypt($password,$cost)
{
$chars='./ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
$salt=sprintf('$2y$%02d$',$cost);
//For PHP < PHP 5.3.7 use this instead
// $salt=sprintf('$2a$%02d$',$cost);
//Create a 22 character salt -edit- 2013.01.15 - replaced rand with mt_rand
mt_srand();
for($i=0;$i<22;$i++) $salt.=$chars[mt_rand(0,63)];
return crypt($password,$salt);
}
例:
$hash=blowfishCrypt('password',10); //This creates the hash
$hash=blowfishCrypt('password',12); //This creates a more secure hash
if(crypt('password',$hash)==$hash){ /*ok*/ } //This checks a password
我知道应该很明显,但是请不要使用“密码”作为密码。
#2楼
PHP 5.5版将内置支持BCrypt,函数password_hash()
和password_verify()
。 实际上,这些只是crypt()
函数的包装,可以使正确使用它变得更加容易。 它负责安全随机盐的生成,并提供良好的默认值。
使用此功能的最简单方法是:
$hashToStoreInDb = password_hash($password, PASSWORD_BCRYPT);
$isPasswordCorrect = password_verify($password, $existingHashFromDb);
此代码将使用BCrypt(算法2y
)对密码进行哈希处理,从OS随机源生成随机盐,并使用默认的cost参数(目前为10)。 第二行检查用户输入的密码是否与已存储的哈希值匹配。
如果要更改cost参数,可以这样进行,将cost参数增加1,就可以将计算散列值所需的时间加倍:
$hash = password_hash($password, PASSWORD_BCRYPT, array("cost" => 11));
与"cost"
参数相反,最好省略"salt"
参数,因为该功能已经尽力创建了密码安全的盐。
对于PHP 5.3.7及更高版本,存在一个兼容包 ,该兼容包来自制作了password_hash()
函数的同一作者。 对于5.3.7之前的PHP版本,不支持带有Unicode安全BCrypt算法2y
crypt()
。 可以用2a
代替它,这是早期PHP版本的最佳替代。
#3楼
那么,您要使用bcrypt吗? 太棒了! 但是,与其他密码学领域一样,您不应该自己进行加密。 如果您需要担心诸如管理密钥,存储盐或生成随机数之类的事情,那您就错了。
原因很简单: 搞砸bcrypt非常容易。 实际上,如果您查看此页面上几乎每段代码,都会注意到它至少侵犯了这些常见问题之一。
面对现实,密码学很难。
留给专家。 将其留给工作人员来维护这些库。 如果您需要做出决定,那就错了。
相反,只需使用一个库。 根据您的要求有几种。
图书馆
这是一些更常见的API的细分。
PHP 5.5 API-(适用于5.3.7+)
从PHP 5.5开始,引入了用于哈希密码的新API。 (我)还为5.3.7+维护了一个垫片兼容性库。 这具有被同行评审和易于使用的实现的好处