最近将一个php项目在转成java项目,经过了解,原php项目使用的是Laravel 框架。php的功能使用java实现比较方便,属于你看得懂逻辑结构就写得出代码那种。随着前端越来越面向对象,php和java都只需要处理业务逻辑对外提供接口数据便可。而今天要和大家分享的是,使用Laravel框架中的推荐加密算法后如何用java实现。
在项目中使用的是laravel的Hash::make,底层的实现 以此可以看出是使用PHP的password_hash()实现的。这个方法有不同的是实现方式,在项目的是采用的默认实现,
string password_hash ( string $password , integer $algo [, array $options ])
它有三个参数:密码、哈希算法、选项。前两项为必须的。 让我们使用password_hash()简单的创建一个哈希密码: 复制代码 代码如下:
$pwd = "123456";
$hash = password_hash($pwd, PASSWORD_DEFAULT);
echo $hash;
上例输出结果类似:
$2y$10$4kAu4FNGuolmRmSSHgKEMe3DbG5pm3diikFkiAKNh.Sf1tPbB4uo2
并且刷新页面该哈希值也会不断的变化。
这里便有了一个疑问,同样的值同意的算法不同的值如何验证如何实现。 上述的方法支持三种算法
PASSWORD_BCRYPT 支持的选项:
我要处理的密码是 因为 password_hash 使用的是 crypt 算法, 因此参与计算 hash值的:
算法(就像身份证开头能知道省份一样, 由盐值的格式决定), cost(默认10) 和 盐值 是在$hash中可以直接看出来的!
所以说, Laravel 中bcrypt的盐值是PHP自动随机生成的字符, 虽然同一个密码每次计算的hash不一样.
但是通过 $hash 和 密码, 却可以验证密码的正确性!
具体来说, 比如这个
$hash = password_hash('password',PASSWORD_BCRYPT,['cost' => 10]);
echo $hash;
// 比如我这次算的是
// $hash = '$2y$10$DyAJOutGjURG9xyKgAaCtOm4K1yezvgNkxHf6PhuLYBCENk61bePm';
那么我们从这个 crypt的hash值中可以看到, 因为以$2y$开头, 所以它的算法是 CRYPT_BLOWFISH .
同时 CRYPT_BLOWFISH 算法盐值格式规定是 :
以$2y$开头 + 一个两位cost参数 + $ + 22位随机字符("./0-9A-Za-z")
$hash(CRYPT_BLOWFISH是固定60位) = 盐值 + 31位单向加密后的值
参见: https://secure.php.net/manual/en/function.crypt.php
验证密码
if (password_verify('password', $hash)) {
echo '密码正确.';
} else {
echo '密码错误!';
}
// 原理是:
if ($hash === crypt('password', '$2y$10$DyAJOutGjURG9xyKgAaCtO')) {
echo '密码正确.';
} else {
echo '密码错误!';
}
在http://stackoverflow.com/questions/3292160/equivalent-of-phps-crypt-function-in-java中有人提到了apache的commons-codes里面的两个类UnixCript 和Md5Crypt
http://shidan66.iteye.com/blog/1974285
http://php.net/manual/zh/function.password-hash.php
https://segmentfault.com/q/1010000004466485
http://www.php.net/manual/zh/function.password-hash.php
https://segmentfault.com/q/1010000011719668
https://blog.csdn.net/zhanghao143lina/article/details/77662547