分享一个 Java 中非常糟糕的 API 设计

查看 145|回复 16
作者:0xD800   
python 代码如下:
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();
}
这是一个微信聊天记录数据库算法。。
orangie   
搜了一下 PBKDF2 的文档: https://www.ietf.org/rfc/rfc2898.txt 其中 password 是一个 string ,那么实现的时候使用 String 对应的 char[]应该是没有问题的。另外既然名称是 password ,使用用户可见的字符来表示也是更合理的。使用字节的密码应该叫做 key 。
lsk569937453   
java 的类库这么多,找一个符合你要求的就可以了。
pocketz   
那么为什么不直接将 byte[] 转为 char[] 呢
BiChengfei   
hashlib.pbkdf2_hmac('sha1', password, salt, iterations, key_length)
我理解你是想使用 sha1 算法对 password 进行 hash 运算,salt 表示加盐,iterations 表示计算次数,key_length 表示 hash 后的长度
非法字符序列,举个例子啊,是指不在 UTF_8 中的字符吗,上来就是”糟糕“、”无语“、”屁“,已 block
0xD800
OP
  
@orangie 请教下 java 有没有用 key 的类 0.0
0xD800
OP
  
@BiChengfei Hex: AC3C90034CF34804A7859144129CA9AEB6B90D07CA874172A374F2000000CAE5 ,麻烦指导一下用 jdk 的 API 算一下 key 出来呗
0xD800
OP
  
@lsk569937453 你说得对 0.0
siweipancc   
看得我一脸懵逼,啥跟啥这是
0xD800
OP
  
@siweipancc 一个计算微信聊天记录数据库密钥的算法,来源: https://mp.weixin.qq.com/s/4DbXOS5jDjJzM2PN0Mp2JA
您需要登录后才可以回帖 登录 | 立即注册

返回顶部