1. 概要

MD5は、広く使用されている暗号化ハッシュ関数であり、128ビットのハッシュを生成します。

この記事では、さまざまなJavaライブラリを使用してMD5ハッシュを作成するためのさまざまなアプローチを紹介します。

2. MessageDigestクラスを使用したMD5

java.security.MessageDigestクラスにはハッシュ機能があります。 アイデアは、最初に MessageDigest を、引数として使用したい種類のアルゴリズムでインスタンス化することです。

MessageDigest.getInstance(String Algorithm)

次に、 update()関数を使用してメッセージダイジェストを更新し続けます。

public void update(byte [] input)

上記の関数は、長いファイルを読み取っている場合に複数回呼び出すことができます。 最後に、 digest()関数を使用してハッシュコードを生成する必要があります。

public byte[] digest()

以下は、パスワードのハッシュを生成して検証する例です。

@Test
public void givenPassword_whenHashing_thenVerifying() 
  throws NoSuchAlgorithmException {
    String hash = "35454B055CC325EA1AF2126E27707052";
    String password = "ILoveJava";
        
    MessageDigest md = MessageDigest.getInstance("MD5");
    md.update(password.getBytes());
    byte[] digest = md.digest();
    String myHash = DatatypeConverter
      .printHexBinary(digest).toUpperCase();
        
    assertThat(myHash.equals(hash)).isTrue();
}

同様に、ファイルのチェックサムを確認することもできます。

@Test
public void givenFile_generatingChecksum_thenVerifying() 
  throws NoSuchAlgorithmException, IOException {
    String filename = "src/test/resources/test_md5.txt";
    String checksum = "5EB63BBBE01EEED093CB22BB8F5ACDC3";
        
    MessageDigest md = MessageDigest.getInstance("MD5");
    md.update(Files.readAllBytes(Paths.get(filename)));
    byte[] digest = md.digest();
    String myChecksum = DatatypeConverter
      .printHexBinary(digest).toUpperCase();
        
    assertThat(myChecksum.equals(checksum)).isTrue();
}

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

3. ApacheCommonsを使用したMD5

org.apache.commons.codec.digest.DigestUtils クラスを使用すると、作業がはるかに簡単になります。

パスワードのハッシュと検証の例を見てみましょう。

@Test
public void givenPassword_whenHashingUsingCommons_thenVerifying()  {
    String hash = "35454B055CC325EA1AF2126E27707052";
    String password = "ILoveJava";

    String md5Hex = DigestUtils
      .md5Hex(password).toUpperCase();
        
    assertThat(md5Hex.equals(hash)).isTrue();
}

4. グアバを使用したMD5

以下は、com.google.common.io.Files.hashを使用してMD5チェックサムを生成するために従うことができる別のアプローチです。

@Test
public void givenFile_whenChecksumUsingGuava_thenVerifying() 
  throws IOException {
    String filename = "src/test/resources/test_md5.txt";
    String checksum = "5EB63BBBE01EEED093CB22BB8F5ACDC3";
        
    HashCode hash = com.google.common.io.Files
      .hash(new File(filename), Hashing.md5());
    String myChecksum = hash.toString()
      .toUpperCase();
        
    assertThat(myChecksum.equals(checksum)).isTrue();
}

Hashing.md5は非推奨であることに注意してください。 ただし、公式ドキュメントが示すように、その理由は、セキュリティ上の懸念から一般的にMD5を使用しないようにアドバイスするためです。 これは、たとえば、MD5を必要とするレガシーシステムと統合する必要がある場合でも、この方法を使用できることを意味します。 それ以外の場合は、SHA-256などのより安全なオプションを検討することをお勧めします。

5. 結論

Java APIと、ApachecommonsやGuavaなどの他のサードパーティAPIには、MD5ハッシュを生成するためのさまざまな方法があります。 プロジェクトの要件とプロジェクトが従う必要のある依存関係に基づいて賢明に選択してください。

いつものように、コードはGithubから入手できます。