Java 和 PHP (Laravel) 的 Bcrypt 加密兼容
后端早期使用的是 Laravel 构建的,用户系统的密码加密方式用的是原生的语法:password_hash
1 | // $hash = password_hash('broly', PASSWORD_DEFAULT); |
现在需要部分业务用到 Java 做用户验证,这里就涉及到密码验证的兼容问题。先来用 spring security 的 BCryptPasswordEncoder 测试一下:
1 | package com.dreamlike.dmlkdemo; |
发现测试通不过。网上查了下 password_hash() 默认的加密算法是 CRYPT_BLOWFISH,官方文档有这样一段描述:
CRYPT_BLOWFISH
- Blowfish hashing with a salt as follows: "$2a$", "$2x$" or "$2y$", a two digit cost parameter, "$", and 22 characters from the alphabet "./0-9A-Za-z". Using characters outside of this range in the salt will cause crypt() to return a zero-length string. The two digit cost parameter is the base-2 logarithm of the iteration count for the underlying Blowfish-based hashing algorithmeter and must be in range 04-31, values outside this range will cause crypt() to fail. Versions of PHP before 5.3.7 only support "$2a$" as the salt prefix: PHP 5.3.7 introduced the new prefixes to fix a security weakness in the Blowfish implementation. Please refer to » this document for full details of the security fix, but to summarise, developers targeting only PHP 5.3.7 and later should use "$2y$" in preference to "$2a$".
可以发现二者之间的区别在于字符串开头 $2a$ 与 $2y$。大意是 $2y$ 开头的是新版本的安全修复。Java 仅支持 $2a$。 其实解决方法很简单,在判断之前,用正则把 $2y$ 改成 $2a$,然后进行判断:
1 | package com.dreamlike.dmlkdemo; |