那么,您要使用bcrypt吗?太棒了!但是,与其他密码学领域一样,您不应该自己进行加密。如果您需要担心诸如管理密钥,存储盐或生成随机数之类的事情,那您就错了。
原因很简单:搞砸bcrypt非常容易。实际上,如果您查看此页面上几乎所有的代码,都会注意到它至少违反了这些常见问题之一。
面对现实,密码学很难。
留给专家。将其留给维护这些库的工作人员使用。如果您需要做出决定,那就错了。
相反,只需使用一个库。根据您的要求有几种。
图书馆
这是一些更常见的API的细分。
PHP 5.5 API-(适用于5.3.7+)
从PHP 5.5开始,引入了用于哈希密码的新API。(我)还为5.3.7+维护了一个垫片兼容性库。这具有被同行评审和易于使用的实现的好处。
function register($username, $password) {
$hash = password_hash($password, PASSWORD_BCRYPT);
save($username, $hash);
}
function login($username, $password) {
$hash = loadHashByUsername($username);
if (password_verify($password, $hash)) {
//login
} else {
// failure
}
}
确实,它的目标是非常简单。
资源:
Zend \ Crypt \ Password \ Bcrypt(5.3.2+)
这是另一个类似于PHP 5.5的API,并且具有相似的用途。
function register($username, $password) {
$bcrypt = new Zend\Crypt\Password\Bcrypt();
$hash = $bcrypt->create($password);
save($user, $hash);
}
function login($username, $password) {
$hash = loadHashByUsername($username);
$bcrypt = new Zend\Crypt\Password\Bcrypt();
if ($bcrypt->verify($password, $hash)) {
//login
} else {
// failure
}
}
资源:
密码库
这是密码哈希的稍微不同的方法。PasswordLib不仅支持bcrypt,还支持大量的哈希算法。它主要用于需要支持与您控制范围之外的旧系统和异构系统的兼容性的情况。它支持大量的哈希算法。并支持5.3.2+
function register($username, $password) {
$lib = new PasswordLib\PasswordLib();
$hash = $lib->createPasswordHash($password, '$2y$', array('cost' => 12));
save($user, $hash);
}
function login($username, $password) {
$hash = loadHashByUsername($username);
$lib = new PasswordLib\PasswordLib();
if ($lib->verifyPasswordHash($password, $hash)) {
//login
} else {
// failure
}
}
参考文献:
PHPASS
这是一个确实支持bcrypt的层,但是它还支持相当强大的算法,如果您无法访问PHP> = 5.3.2 ...,该算法将非常有用。它实际上支持PHP 3.0+(尽管不支持bcrypt)。
function register($username, $password) {
$phpass = new PasswordHash(12, false);
$hash = $phpass->HashPassword($password);
save($user, $hash);
}
function login($username, $password) {
$hash = loadHashByUsername($username);
$phpass = new PasswordHash(12, false);
if ($phpass->CheckPassword($password, $hash)) {
//login
} else {
// failure
}
}
资源资源
注意:不要使用不在openwall上托管的PHPASS替代方案,它们是不同的项目!!!
关于BCrypt
如果您注意到这些库中的每一个都返回一个字符串。这是因为BCrypt在内部如何工作。关于这一点有很多答案。这是我写的选择,我不会在这里复制/粘贴,但链接到:
包起来
有很多不同的选择。选择哪种取决于您。但是,我强烈建议您使用上述库之一为您处理此问题。
同样,如果您crypt()
直接使用,则可能是做错了什么。如果您的代码直接使用hash()
(或md5()
或sha1()
),则几乎肯定是在做错什么。
只是使用图书馆...