我有一个带有MySQL数据库的Dovecot服务器,用于存储用户名和密码。数据库中的密码采用SHA512-CRYPT方案。
我使用脚本在数据库中插入散列密码。
doveadm pw -s SHA512-CRYPT -p password -r 500000
我想使用JAVA应用程序来散列密码。我找到this questions,我尝试使用相同的密码firstpassword
和salt FooBarBaz
创建相同的结果哈希。由于某种原因,我得到的哈希是不同的,虽然我使用相同的哈希算法,盐和密码。
这是我的Java代码:
byte[] password = "firstpassword".getBytes();
byte[] salt = "FooBarBaz".getBytes();
MessageDigest digest = MessageDigest.getInstance("SHA-512");
digest.reset();
digest.update(salt);
byte[] hashed = digest.digest(password);
String encodedHash = Base64.getEncoder().encodeToString(hashed);
System.out.printf("{SHA512-CRYPT}$6$%s$%s", "FooBarBaz",encodedHash);
这会输出哈希:
{SHA512-CRYPT}$6$FooBarBaz$5WPtOnXVI/a6f003WByGKIcsfa6x0ansxiyE8uEfJ0TE5pI+Rv9kcMLgdZboKg7ZSWQgWFg+pIqruvdg6aiP/g==
我还尝试交换salt +密码的顺序来实现它:
digest.update(password);
byte[] hashed = digest.digest(salt);
这给了我:
{SHA512-CRYPT}$6$FooBarBaz$QWS8+W5EWhModF+uO2tcsd55tDxzdzGJ5FurIbEgwVCwKfT5UqwIvBNG1Oyws8bZEFdeGgyD0u6zS1KArvGf9Q==
如果我使用相同的密码和盐,有没有人知道如何在Java中完成相同的哈希结果?
我正在寻找的哈希是:
{SHA512-CRYPT}$6$FooBarBaz$.T.G.7FRJqZ6N2FF7b3BEkr5j37CWhwgvPOOoccrr0bvkBbNMmLCxzqQqKJbNhnhC.583dTBLEuZcDuQe7NEe.
答案 0 :(得分:6)
doveadm
使用Unix crypt系列函数生成散列并将散列输出为Base64编码的字符串。用于编码的字母表(crypt
)是[a-zA-Z0-9./]
(如函数手册页中所述)。但是,java.util.Base64
类使用的字母为[A-Za-z0-9+/]
(符合RFC 4648
,如JavaDoc page for the Base64 class所述。因此,即使散列值相同,它们也会以不同的方式编码。
一个可靠的选择是使用Apache Commons Codec中的Crypt
类作为Crypt.crypt("firstpassword", "$6$FooBarBaz")
(必须使用前缀$6$
来指示Crypt
SHA512-CRYPT
需要使用算法)。这将生成您期望的哈希值。