因为业务的需要,java要实现Django的PBKDF2PasswordHasher加密算法。本来以为算法嘛,知道源码,自己模仿写一套应该很简单,事实却是打脸了!在同事的帮忙下分析了半天的python源码,终于明白加密后的是下面这种格式的字符串:
<algorithm>$<iterations>$<salt>$<hash>
上面就是用于储存用户密码的部分,以美元字符分分隔并由哈希算法、算法迭代次数(工作因数)、随机的salt、以及生成的密码哈希值组成。算法是Django可以使用的,单向哈希或者密码储存算法之一。详细介绍请参考:http://python.usyiyi.cn/translate/django_182/topics/auth/passwords.html
下面的工具类是根据https://gist.github.com/lukaszb/1af1bd4233326e37a8a0代码基础上添加了生成随机的salt。
package test;
/* Example implementation of password hasher similar on Django's PasswordHasher
* Requires Java8 (but should be easy to port to older JREs)
* Currently it would work only for pbkdf2_sha256 algorithm
*/
import java.nio.charset.Charset;
import java.security.NoSuchAlgorithmException;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.KeySpec;
import java.util.Base64;
import java.util.Random;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.PBEKeySpec;
class Hasher {
public final Integer DEFAULT_ITERATIONS = 20000;
public final String algorithm = "pbkdf2_sha256";
public Hasher() {}
public String getEncodedHash(String password, String salt, int iterations) {
// Returns only the last part of whole encoded password
SecretKeyFactory keyFactory = null;
try {
keyFactory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256");
} catch (NoSuchAlgorithmException e) {
System.err.println(