Java 8 通过sha512算法编码的输出不是以$6开头的

Java 8 通过sha512算法编码的输出不是以$6开头的,java-8,sha512,Java 8,Sha512,但是,我们知道前2或3个字符表示哈希算法 即: i.e : "0000" --> c6001d5b2ac3df314204a8f9d7a00e1503c9aba0fd4538645de4bf4cc7e2555cfe9ff9d0236bf327ed3e907849a98df4d330c4bea551017d465b4c1d9b80bcb0 -编码和散列之间有区别吗? 或者故事是什么? 更新: LinuxCrypt命令行生成一个包含86个字符的字符串,而Java8生成1

但是,我们知道前2或3个字符表示哈希算法

即:

   i.e :
        "0000" --> c6001d5b2ac3df314204a8f9d7a00e1503c9aba0fd4538645de4bf4cc7e2555cfe9ff9d0236bf327ed3e907849a98df4d330c4bea551017d465b4c1d9b80bcb0
-编码和散列之间有区别吗? 或者故事是什么? 更新: LinuxCrypt命令行生成一个包含86个字符的字符串,而Java8生成128个字符

  Blowfish --> $2$ or $2a$ 
  SHA-512  --> $6$

不清楚为什么期望JavaAPI函数生成POSIXAPI函数的GNU扩展的输出。此外,当您在Java代码中生成字符串时,您是控制生成字符串大小的人

SHA-512摘要返回的字节数组正好有66个字节,这并不奇怪,因为66个字节*8==512位。这就是SHA-512散列的全部内容。您决定将其编码为十六进制形式,四位需要一个字符,因此512/4==128个字符

顺便说一句,即使对于该功能,也值得习惯现有的API、Java编程语言特性和编码约定:

#man 3 crypt
       MD5     | 22 characters
       SHA-256 | 43 characters
       SHA-512 | 86 characters
但是,如果crypt C函数生成86个字节,则最有可能使用Base64编码,它需要一个字符代表六位,如512/6==85,33…,因此至少需要86个字符

如果您想使用base64编码,可以使用从Java8开始的标准API,对于旧版本,您需要第三方库或自己实现它

public static String sha(String base) {
    try {
        MessageDigest digest = MessageDigest.getInstance("SHA-512");
        StringBuilder hexString = new StringBuilder();
        for(byte b: digest.digest(base.getBytes(StandardCharsets.UTF_8)))
            hexString.append(String.format("%02x", b&0xff));
        return hexString.toString();
    } catch(NoSuchAlgorithmException ex){
        throw new RuntimeException(ex);
    }
}
请注意,编码字符串将有88个字符,因为标准的base64格式有一个填充,即此处的末尾将始终有两个=字符。如果您从SHA-512这样的上下文中知道它必须是512位,那么在存储结果时可以忽略它们:

public static String sha(String base) {
    try{
        MessageDigest digest = MessageDigest.getInstance("SHA-512");
        byte[] hash = digest.digest(base.getBytes(StandardCharsets.UTF_8));
        return Base64.getEncoder().encodeToString(hash);
    } catch(NoSuchAlgorithmException ex){
        throw new RuntimeException(ex);
    }
}

}

crypt3是一种密码哈希算法,仅基于SHA-512

您可以在Apache Commons编解码器项目中找到Java实现:

该算法实际上将第一个SHA-512摘要的结果反馈给它自己数千次,故意放慢速度,因为这使得bruteforce破解密码更加困难

public static String sha(String base) {
    try{
        MessageDigest digest = MessageDigest.getInstance("SHA-512");
        byte[] hash = digest.digest(base.getBytes(StandardCharsets.UTF_8));
        return Base64.getEncoder().encodeToString(hash);
    } catch(NoSuchAlgorithmException ex){
        throw new RuntimeException(ex);
    }
}
public static String sha(String base) {
    try{
        MessageDigest digest = MessageDigest.getInstance("SHA-512");
        byte[] hash = digest.digest(base.getBytes(StandardCharsets.UTF_8));
        String encoded = Base64.getEncoder().encodeToString(hash);
        assert encoded.length()==88 && encoded.endsWith("==");
        return encoded.substring(0, 86);
    } catch(NoSuchAlgorithmException ex){
        throw new RuntimeException(ex);
    }