1. 概要

SHA(Secure Hash Algorithm)は、一般的な暗号化ハッシュ関数の1つです。 暗号化ハッシュを使用して、テキストまたはデータファイルの署名を作成できます。

このチュートリアルでは、さまざまなJavaライブラリを使用してSHA-256およびSHA3-256ハッシュ操作を実行する方法を見てみましょう。

SHA-256 アルゴリズムは、ほぼ一意の固定サイズの256ビット(32バイト)ハッシュを生成します。 これは一方向性関数であるため、結果を復号化して元の値に戻すことはできません。

現在、SHA-2ハッシュは、暗号化の分野で最も安全なハッシュアルゴリズムと見なされているため、広く使用されています。

SHA-3 は、SHA-2に続く最新のセキュアハッシュ標準です。 SHA-2と比較すると、SHA-3は、一意の一方向ハッシュを生成するための異なるアプローチを提供し、一部のハードウェア実装でははるかに高速になる可能性があります。 SHA-256と同様に、SHA3-256はSHA-3の256ビット固定長アルゴリズムです。

NIST は2015年にSHA-3をリリースしたため、当面はSHA-2ほど多くのSHA-3ライブラリはありません。 組み込みのデフォルトプロバイダーでSHA-3アルゴリズムが利用可能になったのは、JDK9までではありません。

それでは、SHA-256から始めましょう。

2. MessageDigestクラスJava

Javaは、SHA-256ハッシュ用の組み込みのMessageDigestクラスを提供します。

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

ただし、ここでは、カスタムのバイトから16進数へのコンバーターを使用して、ハッシュ値を16進数で取得する必要があります。

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();
}

MessageDigestはスレッドセーフではないことに注意する必要があります。したがって、すべてのスレッドに新しいインスタンスを使用する必要があります。

3. Guavaライブラリ

Google Guavaライブラリは、ハッシュ用のユーティリティクラスも提供します。

まず、依存関係を定義しましょう。

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

次に、Guavaを使用して文字列をハッシュする方法を次に示します。

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

4. ApacheCommonsコーデック

同様に、ApacheCommonsコーデックを使用することもできます。

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

SHA-256ハッシュをサポートするユーティリティクラス( DigestUtils )は次のとおりです。

String sha256hex = DigestUtils.sha256Hex(originalString);

5. 弾む城図書館

5.1. Mavenの依存関係

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

5.2. バウンシーキャッスルライブラリを使用したハッシュ

Bouncy Castle APIは、16進データをバイトに変換して元に戻すためのユーティリティクラスを提供します。

ただし、最初に組み込みのJavaAPIを使用してダイジェストを設定する必要があります。

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

それでは、SHA3-256を続けましょう。 JavaのSHA3-256ハッシュは、SHA-256とそれほど違いはありません。

6.1. MessageDigestクラスJava

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. ApacheCommonsコーデック

Apache Commons Codecsは、MessageDigestクラスに便利なDigestUtilsラッパーを提供します。

このライブラリは、バージョン 1.11 からSHA3-256のサポートを開始し、にはJDK9+も必要です。

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

6.3. Keccak-256

Keccak-256は、もう1つの人気のあるSHA3-256ハッシュアルゴリズムです。 現在、標準のSHA3-256の代替として機能します。 Keccak-256は、標準のSHA3-256と同じセキュリティレベルを提供し、パディングルールのみがSHA3-256と異なります。 Moneroなどのいくつかのブロックチェーンプロジェクトで使用されています。

ここでも、Keccak-256ハッシュを使用するには、BouncyCastleLibraryをインポートする必要があります。

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);

BouncyCastleAPIを使用してハッシュを実行することもできます。

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

7. 結論

この簡単な記事では、組み込みライブラリとサードパーティライブラリの両方を使用して、JavaでSHA-256およびSHA3-256ハッシュを実装するいくつかの方法について説明しました。

例のソースコードは、GitHubプロジェクトにあります。