SHA-256 and SHA3-256 Hashing in Java – Java中的SHA-256和SHA3-256哈希算法

最后修改: 2016年 11月 20日

中文/混合/英文(键盘快捷键:t)

1. Overview

1.概述

The SHA (Secure Hash Algorithm) is one of the popular cryptographic hash functions. A cryptographic hash can be used to make a signature for a text or a data file.

SHA(安全哈希算法)是流行的加密哈希函数之一。加密散列可以用来为文本或数据文件做一个签名。

In this tutorial, let’s have a look at how we can perform SHA-256 and SHA3-256 hashing operations using various Java libraries.

在本教程中,让我们看看如何使用各种Java库进行SHA-256和SHA3-256散列操作。

The SHA-256 algorithm generates an almost unique, fixed-size 256-bit (32-byte) hash. This is a one-way function, so the result cannot be decrypted back to the original value.

SHA-256算法生成一个几乎唯一的、固定大小的256位(32字节)散列。这是一个单向函数,所以结果不能被解密回原始值。

Currently, SHA-2 hashing is widely used, as it is considered the most secure hashing algorithm in the cryptographic arena.

目前,SHA-2散列算法被广泛使用,因为它被认为是加密领域中最安全的散列算法。

SHA-3 is the latest secure hashing standard after SHA-2. Compared to SHA-2, SHA-3 provides a different approach to generate a unique one-way hash, and it can be much faster on some hardware implementations. Similar to SHA-256, SHA3-256 is the 256-bit fixed-length algorithm in SHA-3.

SHA-3是SHA-2之后最新的安全散列标准。与SHA-2相比,SHA-3提供了一种不同的方法来生成唯一的单向散列,而且在某些硬件实现上可以快很多。与SHA-256类似,SHA3-256是SHA-3中的256位固定长度算法。

NIST released SHA-3 in 2015, so there are not quite as many SHA-3 libraries as SHA-2 for the time being. It’s not until JDK 9 that SHA-3 algorithms were available in the built-in default providers.

NIST在2015年发布了SHA-3,所以暂时还没有像SHA-2那样多的SHA-3库。直到JDK 9,SHA-3算法才在内置的默认提供者中出现。

Now let’s start with SHA-256.

现在让我们从SHA-256开始。

2. MessageDigest Class in Java

2.Java中的MessageDigest

Java provides inbuilt MessageDigest class for SHA-256 hashing:

Java提供了内置的MessageDigest类用于SHA-256散列。

MessageDigest digest = MessageDigest.getInstance("SHA-256");
byte[] encodedhash = digest.digest(
  originalString.getBytes(StandardCharsets.UTF_8));

However, here we have to use a custom byte to hex converter to get the hashed value in hexadecimal:

然而,在这里我们必须使用一个自定义的字节到十六进制的转换器来获得十六进制的散列值。

private static String bytesToHex(byte[] hash) {
    StringBuilder hexString = new StringBuilder(2 * hash.length);
    for (int i = 0; i < hash.length; i++) {
        String hex = Integer.toHexString(0xff & hash[i]);
        if(hex.length() == 1) {
            hexString.append('0');
        }
        hexString.append(hex);
    }
    return hexString.toString();
}

We need to be aware that the MessageDigest is not thread-safe. Consequently, we should use a new instance for every thread.

我们需要注意的是,MessageDigest不是线程安全的。因此,我们应该为每个线程使用一个新实例。

3. Guava Library

3.瓜娃图书馆

The Google Guava library also provides a utility class for hashing.

Google Guava库也提供了一个用于散列的实用类。

First, let’s define the dependency:

首先,让我们定义一下依赖关系。

<dependency>
    <groupId>com.google.guava</groupId>
    <artifactId>guava</artifactId>
    <version>31.0.1-jre</version>
</dependency>

Next, here’s how we can use Guava to hash a String:

接下来,我们来看看如何使用Guava对一个字符串进行哈希处理。

String sha256hex = Hashing.sha256()
  .hashString(originalString, StandardCharsets.UTF_8)
  .toString();

4. Apache Commons Codecs

4.Apache Commons Codecs

Similarly, we can also use Apache Commons Codecs:

同样地,我们也可以使用Apache Commons Codecs。

<dependency>
    <groupId>commons-codec</groupId>
    <artifactId>commons-codec</artifactId>
    <version>1.11</version>
</dependency>

Here’s the utility class — called DigestUtils — that supports SHA-256 hashing:

这里是支持SHA-256散列的实用类–称为DigestUtils

String sha256hex = DigestUtils.sha256Hex(originalString);

5. Bouncy Castle Library

5.充气城堡图书馆

5.1. Maven Dependency

5.1.Maven的依赖性

<dependency>
    <groupId>org.bouncycastle</groupId>
    <artifactId>bcprov-jdk15on</artifactId>
    <version>1.60</version>
</dependency>

5.2. Hashing Using the Bouncy Castle Library

5.2.使用Bouncy Castle库进行哈希运算

The Bouncy Castle API provides a utility class for converting hex data to bytes and back again.

Bouncy Castle API提供了一个实用类,用于将十六进制数据转换为字节,然后再转换回来。

However, we need to populate a digest using the built-in Java API first:

然而,我们需要先用内置的Java API填充一个摘要。

MessageDigest digest = MessageDigest.getInstance("SHA-256");
byte[] hash = digest.digest(
  originalString.getBytes(StandardCharsets.UTF_8));
String sha256hex = new String(Hex.encode(hash));

6. SHA3-256

6.SHA3-256

Now let’s continue with SHA3-256. SHA3-256 hashing in Java isn’t that different from SHA-256.

现在让我们继续讨论SHA3-256。Java中的SHA3-256散列与SHA-256并没有什么不同。

6.1. MessageDigest Class in Java

6.1.MessageDigest类在Java中的应用

Starting from JDK 9, we can simply use the built-in SHA3-256 algorithm:

从JDK 9开始,我们可以简单地使用内置的SHA3-256算法。

final MessageDigest digest = MessageDigest.getInstance("SHA3-256");
final byte[] hashbytes = digest.digest(
  originalString.getBytes(StandardCharsets.UTF_8));
String sha3Hex = bytesToHex(hashbytes);

6.2. Apache Commons Codecs

6.2.Apache Commons Codecs

Apache Commons Codecs provides a convenient DigestUtils wrapper for the MessageDigest class.

Apache Commons Codecs为MessageDigest类提供了一个方便的DigestUtils包装器。

This library began to support SHA3-256 since version 1.11, and it requires JDK 9+ as well:

这个库从1.11版本开始支持SHA3-256,并且要求JDK 9+也是如此。

String sha3Hex = new DigestUtils("SHA3-256").digestAsHex(originalString);

6.3. Keccak-256

6.3.Keccak-256[/strong]

Keccak-256 is another popular SHA3-256 hashing algorithm. Currently, it serves as an alternative to the standard SHA3-256. Keccak-256 delivers the same security level as the standard SHA3-256, and it differs from SHA3-256 only on the padding rule. It has been used in several blockchain projects, such as Monero.

Keccak-256是另一种流行的SHA3-256散列算法。目前,它是标准SHA3-256的替代品。Keccak-256提供了与标准SHA3-256相同的安全级别,它与SHA3-256的不同之处仅在于填充规则。它已被用于几个区块链项目,如Monero

Again, we need to import the Bouncy Castle Library to use Keccak-256 hashing:

同样,我们需要导入Bouncy Castle库来使用Keccak-256散列。

Security.addProvider(new BouncyCastleProvider());
final MessageDigest digest = MessageDigest.getInstance("Keccak-256");
final byte[] encodedhash = digest.digest(
  originalString.getBytes(StandardCharsets.UTF_8));
String sha3Hex = bytesToHex(encodedhash);

We can also make use of the Bouncy Castle API to do the hashing:

我们还可以利用Bouncy Castle API来做散列。

Keccak.Digest256 digest256 = new Keccak.Digest256();
byte[] hashbytes = digest256.digest(
  originalString.getBytes(StandardCharsets.UTF_8));
String sha3Hex = new String(Hex.encode(hashbytes));

7. Conclusion

7.结论

In this quick article, we had a look at a few ways of implementing SHA-256 and SHA3-256 hashing in Java, using both built-in and third-party libraries.

在这篇快速文章中,我们看了一些在Java中实现SHA-256和SHA3-256散列的方法,使用了内置和第三方的库。

The source code of the examples can be found in the GitHub project.

示例的源代码可以在GitHub项目中找到。