我正在开发一个应用程序,在这个应用程序中,我必须比较数据库中的2个哈希密码,其中一个密码是用php生成的 $Password = password_hash($RawPassword, PASSWORD_BCRYPT);
另一个被发送到数据库与php散列密码进行比较的密码是用java生成的 String hashedPassword = BCrypt.hashpw(password);
从php7.0开始,salt是自动生成的,如何知道php中应用了什么salt,以便将其应用到java代码中?或者有没有一种方法仍然可以指定不再出现在php哈希文档中的salt?
1条答案
按热度按时间xa9qqrwz1#
大多数bcrypt impls背后的标准思想是,数据库中的东西看起来像
$2y$10$AB
其中a是22个字符,b是31个字符,总共60个字符。a是:left(base64(salt + 00 + 00), 22)
b是:left(base64(bcryptraw(salt + pass)), 31)
. (2y
指哈希算法/编辑:2y和2a或多或少可以互换;大多数bcrypt impls对它们的处理是相同的,哪一个在那里并不重要。这个10
指所用的bcrypt轮数。10是常见的,通常是你想要的)。哪里:
base64(X)
=应用base64转换,使用。和/作为第63和64个字符。+
是串联的,即。salt
(16字节数组)添加2个零字节。left(chars, size)
意思是:拿第一个size
把剩下的扔掉。salt
盐的单位是字节和pass
是密码,通过utf\ U 8转换为字节(如果不通过utf-8转换,通常是$2a$,你应该升级,在他们的密码中有非ascii字符的人在旧的$2a$模式中得到相当糟糕的哈希!这个字符串包含bcrypt impl需要检查给定密码是否正确的所有内容。因此,所有非白痴bcrypt库impl只有两种方法,没有其他方法:
编辑:注意:一个真正设计良好的加密库调用这些方法
processNewPassword
以及checkExistingPassword
为了避免引起你问这个问题的那种困惑,但不幸的是,似乎没有人有足够的财力思考他们的名字暗示了什么。很不幸。安全很难。如果您的bcryptapi不是这样工作的,那么请将其删除,并找到一个这样工作的标准实现。
听起来你用错方法了。要检查密码,不要使用hashpass。使用checkpass,或者在impl中使用checkpass(它可能被称为
checkPw
或者verifyPw
或者validate
,等等。它需要两个字符串)。因此,您不应该生成盐,也不应该从这样的字符串中提取盐。让bcrypt lib来做。标准bcrypt库生成的那些“散列”(即
$2y$
(弦)可以互换;php库可以生成em,java库可以检查em,反之亦然。如果必须提取盐(但不要):
以这22个字符为例,在
$protocol$rounds$
部分。在后面加上'aa'。
base64解码结果。
这会得到18个字节。抛出最后2个字节,其中包含垃圾。
剩下的16个字节是salt。
你绝对不应该写这个-你的bcrypt库会这样做。