Java SHA 未唤醒。哈希值不等于字符串。我的编码有问题吗?

Java SHA not woking. Hash value dosen't equal String. Is there an issue with my encoding?

基本上我都有这个

   if (args.length != 1) {
        System.err.println("Usage: java MyMd5 <message>");
        System.exit(1);
    }
    try {
        // get message
        byte[] message = args[0].getBytes("UTF8");
        // create message digest object for MD5
        MessageDigest messageDigest = MessageDigest.getInstance("SHA");
        // System.out.println("Provider: " +
        messageDigest.getProvider().getInfo();
        // create message digest
        messageDigest.update(message);
        byte[] md = messageDigest.digest();
        // print result
        System.out.println("Message Digest Algorithm: MD5");
        System.out.println("Message: " + new String(message));
        System.out.println("Message Digest: \"" + new String(md, "UTF8") + "\"");
        String HashPassword=new String(md, "UTF8");
        System.out.println(HashPassword);
        System.out.println(HashPassword.equals("???8p???W?B:??N?~"));

但不知何故,当我尝试比较它时,它返回 false。我的编码有问题吗?谢谢!

    Message Digest Algorithm: MD5 
    Message: pass123
    Message Digest: "???8p???W?B:??N?~"
    ???8p???W?B:??N?~
    false

问题在于不必要的编码,使用 md5 我们必须以正确的方式对字符串进行编码,而不是使用 UTF8 编码

public static void main(String[] args) throws Exception {
    String pass = "pass123";
    byte[] message = pass.getBytes();
    MessageDigest messageDigest = MessageDigest.getInstance("SHA");
    messageDigest.update(message);
    byte[] md = messageDigest.digest();
    StringBuffer sb = new StringBuffer();
    for (int i = 0; i < md.length; i++) {
        sb.append(Integer.toString((md[i] & 0xff) + 0x100, 16).substring(1));
    }
    System.out.println("encoded pass:" + sb.toString());
    System.out.println(sb.toString().equals("aafdc23870ecbcd3d557b6423a8982134e17927e"));
}

如果我正确理解了你的问题,你想将新生成的散列字符串与现有散列字符串(存储在数据库或其他地方)进行比较。上面提供的代码是可能的,如果您将生成的值(而不是从控制台复制)存储到数据库中,然后将其与新生成的值进行比较,您将得到 true

但是当您生成散列时,它包含符号(字符),在任何字符串编码中都没有正确的表示。所以,没有人不将散列存储为纯字符串。通常它们存储在 hex string 表示或 Base64 表示中。

使用下面提供的 hex strings 实现:

public static void main(String[] args) throws Exception { // args = ["Hello world"]
if (args.length != 1) {
    System.err.println("Usage: java MyMd5 <message>");
    System.exit(1);
}
// get message
byte[] message = args[0].getBytes("UTF8"); //You may have problems with encoding here. In Windows, for example, with symbols that are out of English alphabet range  
// create message digest object for MD5
MessageDigest messageDigest = MessageDigest.getInstance("SHA");
// System.out.println("Provider: " +
messageDigest.getProvider().getInfo();
// create message digest
messageDigest.update(message);
byte[] md = messageDigest.digest();
System.out.println("Digest: " + byteArrayToHexString(md));
System.out.println("Is equals? " + byteArrayToHexString(md).equals("7b502c3a1f48c8609ae212cdfb639dee39673f5e"));
}

private static String byteArrayToHexString(byte[] array) {
    StringBuilder result = new StringBuilder(array.length);
    IntStream.range(0, array.length)
        .forEach(i -> result.append(Integer.toString( (array[i] & 0xff) + 0x100, 16).substring(1)));
    return result.toString();
}

此外,在提供的示例中提到您正在使用 MD5,但实际上它是 SHAMessageDigest messageDigest = MessageDigest.getInstance("SHA");