sha-256-hashing-java
SHA-256 and SHA3-256 Hashing in Java
1. Overview
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. In this tutorial, let’s have a look how we can perform SHA-256 and SHA3-256 hashing operations using various Java libraries.
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.
Currently, SHA-2 hashing is widely used as it is being considered as the most secure hashing algorithm in the cryptographic arena.
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.
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.
Now, let’s start with SHA-256.
Further reading:
Locality-Sensitive Hashing in Java Using Java-LSH
A quick and practical guide to applying the Locality-Sensitive Hashing algorithm in Java using the java-lsh library.
2. MessageDigest Class in Java
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) {
StringBuffer hexString = new StringBuffer();
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();
}
3. Guava Library
First, let’s define the dependency:
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>20.0</version>
</dependency>
Now, here’s how we can use Guava to hash a String:
String sha256hex = Hashing.sha256()
.hashString(originalString, StandardCharsets.UTF_8)
.toString();
4. 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:
String sha256hex = DigestUtils.sha256Hex(originalString);
5. Bouncy Castle Library
<dependency> <groupId>org.bouncycastle</groupId> <artifactId>bcprov-jdk15on</artifactId> <version>1.60</version> </dependency>
5.2. Hashing Using the Bouncy Castle Library
However, it is required to populate a digest using the built-in Java API first:
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.1. MessageDigest Class in Java
Starting from JDK 9, we can simply use the built-in SHA3-256 algorithm:
final MessageDigest digest = MessageDigest.getInstance(SHA3_256);
final byte[] hashbytes = digest.digest(
originalString.getBytes(StandardCharsets.UTF_8));
String sha3_256hex = bytesToHex(hashbytes);
6.2. Apache Commons Codecs
Apache Commons Codecs provides a convenient DigestUtils wrapper for the MessageDigest class. This library began to support SHA3-256 since version 1.11 and it requires JDK 9+ as well:
String sha3_256hex = new DigestUtils(SHA3_256).digestAsHex(originalString);
6.3. Keccak-256
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 Monoro.
Again, we need to import the Bouncy Castle Library to use Keccak-256 hashing:
Security.addProvider(new BouncyCastleProvider());
final MessageDigest digest = MessageDigest.getInstance(KECCAK_256);
final byte[] encodedhash = digest.digest(
originalString.getBytes(StandardCharsets.UTF_8));
String sha3_256hex = bytesToHex(encodedhash);
We can also make use of the Bouncy Castle API to do the hashing:
Keccak.Digest256 digest256 = new Keccak.Digest256();
byte[] hashbytes = digest256.digest(
originalString.getBytes(StandardCharsets.UTF_8));
String sha3_256hex = new String(Hex.encode(hashbytes));
7. Conclusion
In this quick article, we had a look at few ways of implementing SHA-256 and SHA3-256 hashing in Java, using both built-in and third-party libraries.
The source code of the examples above can be found on the GitHub project.