有谁能告诉我为什么以下代码并不总是返回相同的哈希? AFAIK哈希可能不同的唯一方法是由于随机盐,但根据文档我通过将盐大小设置为0来禁用盐。
public static void main(String[] args ) {
char[] password = "test_pass".toCharArray();
String str = encodePassword(password);
System.out.printf(
"Byte digest '%s'\n",
String.valueOf(Hex.encodeHex(Base64.decodeBase64(str)))
);
}
static StandardByteDigester digester = new StandardByteDigester();
{
digester.setAlgorithm("SHA-256");
digester.setIterations(100000);
digester.setSaltSizeBytes(0);
digester.initialize();
}
public static String encodePassword(char[] rawPass) {
return new String(Base64.encodeBase64(digester.digest(toBytes(rawPass))));
}
public static byte[] toBytes(char[] ch) {
Charset charset = Charset.defaultCharset();
ByteBuffer buff = charset.encode(CharBuffer.wrap(ch));
byte[] tmp = new byte[buff.limit()];
buff.get(tmp);
return tmp;
}
答案 0 :(得分:3)
您的错误与您在实例初始化程序块而非静态初始化程序块中初始化静态字段StandardByteDigester digester
这一事实有关,因此它是永远不会打电话,因为你永远不会创建你的类的实例,所以最后它使用默认配置和随机盐。
试试这个:
static {
digester.setAlgorithm("SHA-256");
digester.setIterations(100000);
digester.setSaltSizeBytes(0);
digester.initialize();
}
如果您的方法encodePassword
使用String
代替char
数组,您的代码可以简化,因为您只需将getBytes(Charset)
称为下一个:
public static String encodePassword(String rawPass) {
return new String(
Base64.encodeBase64(digester.digest(rawPass.getBytes(StandardCharsets.UTF_8))),
StandardCharsets.US_ASCII
);
}
NB:依靠平台的默认字符集不是一个好习惯,因为您的代码将依赖于平台,所以这里基础64个字符都包含在US_ASCII
中,让我们使用这个charset进行解码。