java - 没有盐的 sha-256 并不总是返回相同的哈希值

标签 java encryption sha256 sha jasypt

谁能告诉我为什么下面的代码并不总是返回相同的哈希值?据我所知,哈希值可能不同的唯一方法是随机盐,但根据文档,我通过将盐大小设置为 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;    
}

最佳答案

您的错误与您在实例初始化 block 而不是静态初始化 block 中初始化静态字段StandardByteDigester digester有关这样它就不会被调用,因为您永远不会创建类的实例,所以最后它使用默认配置和随机盐。

试试这个:

static {
    digester.setAlgorithm("SHA-256");
    digester.setIterations(100000);
    digester.setSaltSizeBytes(0);
    digester.initialize();
}

如果您的方法 encodePassword 使用 String 而不是 char 数组,您的代码可以被简化,因为您可以简单地调用 getBytes (字符集) 如下:

public static String encodePassword(String rawPass) {
    return new String(
        Base64.encodeBase64(digester.digest(rawPass.getBytes(StandardCharsets.UTF_8))),
        StandardCharsets.US_ASCII
    );
}

注意:依赖平台的默认字符集不是一个好的做法,因为您的代码将依赖于平台,所以这里因为 base 64 字符都包含在 US_ASCII,让我们使用这个字符集来解码。

关于java - 没有盐的 sha-256 并不总是返回相同的哈希值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40398664/

相关文章:

java - Linux/Ubuntu - 在不使用 FreeTTS 的情况下从 Java 进行语音合成

java - 当我的应用程序停止时我该如何捕获?

c++加解密源码

encryption - ssl_accept上的“no shared cipher”,为什么?

linux - 生成字符串,此字符串的 SHA256 前两个字节等于 0

java - 如何在 Jersey Client 中引发自定义异常?

java - 启动 Eclipse 平台时出现 MESSAGE 异常

c++ - 在 Windows 7 上运行的 QCA(Qt C++ 加密库)问题

c - 交换uint64_t的高位部分和低位部分的数学意义是什么?

java - php base64_encode hash_hmac 和 java 给出了不同的结果