hashlib.pbkdf2_hmac('sha1', bytes.fromhex('******'), bytes.fromhex('00000000000000000000000000000000'), 64000, 32)
需要用 Java 实现一版,但是发现 java 的 password 参数要传 char[],然后底层转 bytes ,代码如下:
// com.sun.crypto.provider.PBKDF2KeyImpl#getPasswordBytes
private static byte[] getPasswordBytes(char[] passwd) {
CharBuffer cb = CharBuffer.wrap(passwd);
ByteBuffer bb = UTF_8.encode(cb);
int len = bb.limit();
byte[] passwdBytes = new byte[len];
bb.get(passwdBytes, 0, len);
bb.clear().put(new byte[len]);
return passwdBytes;
}
真无语了,这么写相当于密码只能用字符串转 char[]了,不能用二进制的 password ,如果 password 是非法字符序列就个屁了。
/**
* hashlib.pbkdf2_hmac('sha1', password, salt, iterations, key_length)
*/
private static byte[] generateKey(byte[] password, byte[] salt, int iterationCount, int keyLength) throws Exception {
// 由于 password 非字符序列导致 new String 后数据失真,底层无法还原会原始 bytes 。
char[] encoded = new String(password, StandardCharsets.UTF_8).toCharArray();
// 创建密钥规范
KeySpec spec = new PBEKeySpec(encoded, salt, iterationCount, keyLength * 8);
// 使用 PBKDF2WithHmacSHA1 算法创建密钥工厂
SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
// 生成密钥
SecretKey secretKey = factory.generateSecret(spec);
return secretKey.getEncoded();
}
这是一个微信聊天记录数据库算法。。