如何在JAVA中为Dovecot使用SHA512-CRYPT?

时间:2015-07-14 08:17:33

标签: java sha512 dovecot

我有一个带有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.

1 个答案:

答案 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需要使用算法)。这将生成您期望的哈希值。