如何在Java中使用SHA-256哈希某个字符串?

297

我如何在Java中使用 SHA-256 哈希一些 String


2
可能是Java中通过SHA-256哈希字符串的重复问题。 - mmmmmm
1
https://www.baeldung.com/sha-256-hashing-java - Barett
18个回答

5

该方法返回用零进行左填充的String

Java 10及以后版本:

public static String sha256(String text) {
    try {
        var messageDigest = MessageDigest.getInstance("SHA-256");
        var hash = messageDigest.digest(text.getBytes(StandardCharsets.UTF_8));
        
        return String.format("%064x", new BigInteger(1, hash));
    }
    catch (NoSuchAlgorithmException e) {
        e.printStackTrace();
        return null;
    }
}

Java 8:

public static String sha256(String text) {
    try {
        MessageDigest messageDigest = MessageDigest.getInstance("SHA-256");
        byte[] hash = messageDigest.digest(text.getBytes(StandardCharsets.UTF_8));
        
        return String.format("%064x", new BigInteger(1, hash));
    }
    catch (NoSuchAlgorithmException e) {
        e.printStackTrace();
        return null;
    }
}

顺便提一下,你可以使用"%064X"来获得大写的结果。

例子:

System.out.println(sha256("hello world 1"));

与Linux命令的比较:

$ echo -n 'hello world 1' | sha256sum 063dbf1d36387944a5f0ace625b4d3ee36b2daefd8bdaee5ede723637efb1cf4 -

该命令将“hello world 1”字符串作为输入,并通过SHA-256算法生成其哈希值。与Linux中的sha256sum命令相比,该命令没有在结尾添加文件名,而是直接输出了哈希值和短横线符号“-”。

4

这是我一直用来进行哈希的东西:

String pass = "password";

MessageDigest messageDigest = MessageDigest.getInstance("SHA-256");
byte hashBytes[] = messageDigest.digest(pass.getBytes(StandardCharsets.UTF_8));
BigInteger noHash = new BigInteger(1, hashBytes);
String hashStr = noHash.toString(16);

输出:5e884898da28047151d0e56f8dc6292773603d0d6aabbdd62a11ef721d1542d8


4

这是我使用 Kotlin 的方法:

private fun getHashFromEmailString(email : String) : String{
    val charset = Charsets.UTF_8
    val byteArray = email.toByteArray(charset)
    val digest = MessageDigest.getInstance("SHA-256")
    val hash = digest.digest(byteArray)

    return hash.fold("", { str, it -> str + "%02x".format(it)})
}

嗨,我刚刚尝试了你的代码,因为我需要在Android Studio中哈希密码,但是你的代码返回类似于[B@188363e这样的东西,而不是加密后的密码。此外,每次调用此函数时似乎都会得到不同的结果。 - user10021033
1
你忘记了 return hash.fold("", { str, it -> str + "%02x".format(it)}) 这一行代码,它返回的是加密后的密码而不是对象本身。 - user10021033
1
是的,你说得对,让我用你的修复更新答案。谢谢 :) - Samuel Luís

1
您可以按照以下方式使用MessageDigest:

public static String getSHA256(String data){
    StringBuffer sb = new StringBuffer();
    try{
        MessageDigest md = MessageDigest.getInstance("SHA-256");
        md.update(data.getBytes());
        byte byteData[] = md.digest();

        for (int i = 0; i < byteData.length; i++) {
         sb.append(Integer.toString((byteData[i] & 0xff) + 0x100, 16).substring(1));
        }
    } catch(Exception e){
        e.printStackTrace();
    }
    return sb.toString();
}

1
public static String sha256(String s) {
    try {
        return DatatypeConverter.printHexBinary(MessageDigest.getInstance("SHA-256").digest(s.getBytes(StandardCharsets.UTF_8))).toLowerCase();
    } catch (NoSuchAlgorithmException e) {
        e.printStackTrace();
    }
    return null;
}

1
你的回答可以通过提供更多支持信息来改进。请编辑以添加进一步的细节,例如引用或文档,以便他人可以确认你的答案是正确的。您可以在帮助中心中找到有关如何编写良好答案的更多信息。 - Community

1

下面是一种方法,演示了如何使用 sha-256 算法对 String 进行哈希,并以 hex 格式编码结果。这是一种常用的格式,用于对密码进行哈希并存储在数据库中:

public static String sha256(final String data) {
    try {
        final byte[] hash = MessageDigest.getInstance("SHA-256").digest(data.getBytes(StandardCharsets.UTF_8));
        final StringBuilder hashStr = new StringBuilder(hash.length);

        for (byte hashByte : hash)
            hashStr.append(Integer.toHexString(255 & hashByte));

        return hashStr.toString();
    } catch (NoSuchAlgorithmException e) {
        e.printStackTrace();
        return null;
    }
}

有些情况下,使用这种方法会生成错误的哈希值。尝试对字符串“abcd”进行哈希处理。期望结果是:88d4266fd4e6338d13b845fcf289579d209c897823b9217da3e161936f031589;但实际上生成的是88d4266fd4e6338d13b845fcf289579d209c897823b9217da3e161936f31589,缺少一个零。 - Ráfagan

0
在Java中,使用 MessageDigest 类来计算加密哈希值。该类提供了加密哈希函数(MD5, SHA-1, 和SHA-256) 来查找文本的哈希值。
下面是使用 SHA-256 算法的代码示例。
public void printHash(String str) throws NoSuchAlgorithmException {

MessageDigest md=MessageDigest.getInstance("SHA-256");

byte[] sha256=md.digest(str.getBytes(StandardCharsets.UTF_8));

   for(byte b : sha256){

      System.out.printf("%02x",b);

  }
}

-3
private static String getMessageDigest(String message, String algorithm) {
 MessageDigest digest;
 try {
  digest = MessageDigest.getInstance(algorithm);
  byte data[] = digest.digest(message.getBytes("UTF-8"));
  return convertByteArrayToHexString(data);
 } catch (NoSuchAlgorithmException | UnsupportedEncodingException e) {
  // TODO Auto-generated catch block
  e.printStackTrace();
 }
 return null;
}

您可以使用不同的算法调用上述方法,例如以下方式。

getMessageDigest(message, "MD5");
getMessageDigest(message, "SHA-256");
getMessageDigest(message, "SHA-1");

您可以参考此链接获取完整的应用程序。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接