如何用与FOSUserBundle相同的方式用java编码密码

时间:2018-03-24 18:03:59

标签: java fosuserbundle encode salt

我的数据库包含一个带有salt和password列的用户表。 FOSUserBundle使用sha512

# app/config/security.yml
# ...

encoders:
    "FOS\UserBundle\Model\UserInterface": sha512

但不是全部,还有其他参数,如迭代次数,散列算法,成本,key_lenght,编码为base64等,我为这些参数拍了一张图像。 strongly advises against using the extra() method

在我的java应用程序中,我需要以与fosuser相同的方式对输入密码进行编码... 我试图使用org.apache.commons.codec.digest.Crypt,我不知道如何修复像fosuser这样的参数

1 个答案:

答案 0 :(得分:1)

Tomcat有一个API级别MessageDigestCredentialHandler,它可以完成您所描述的大部分内容。如果它不完全符合您的需要,它的源代码应该为您提供足够的指针来处理盐和迭代。

首先它可以编码或改变密码:

MessageDigestCredentialHandler credentialHandler = new MessageDigestCredentialHandler();
credentialHandler.setAlgorithm("SHA-512");
credentialHandler.setSaltLength(16);
credentialHandler.setIterations(5);
credentialHandler.mutate("password");
-> 5e0bdcf374c9c36b8930f23579ca0297$5$2c72f01ce132a1d070e67ad4730f3c26dba6d1dce7d32c6d8fe127afc952cd02308bdbdd45333e71f4dfed57bc5288ce501da30228907b9d49f5932896c025a2

注意结果字符串如何有一个盐,然后是$,然后是迭代次数,另一个$和(十六进制)编码的密码。

如果您的数据库中使用的是十六进制编码,那么您也可以在一个匹配密码的好地方:

MessageDigestCredentialHandler credentialHandler = new MessageDigestCredentialHandler();
credentialHandler.setAlgorithm("SHA-512");
String salt = "5e0bdcf374c9c36b8930f23579ca0297";
int iterations = 5;
String hexPassword = "2c72f01ce132a1d070e67ad4730f3c26dba6d1dce7d32c6d8fe127afc952cd02308bdbdd45333e71f4dfed57bc5288ce501da30228907b9d49f5932896c025a2";
credentialHandler.matches("password", salt + "$" + iterations + "$" + hexPassword);
-> true

如果salt和/或密码是base 64编码的,还有更多工作要做,但请查看source for MessageDigestCredentialHandler.matches(String, String)。它确实在那里处理base64编码,但是从阅读开始看起来似乎不支持多次迭代。我建议看看它是如何进行十六进制编码路由的迭代的。