MD5 Hashing in Java – Java中的MD5哈希算法

最后修改: 2016年 9月 29日

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

1. Overview

1.概述

MD5 is a widely used cryptographic hash function, which produces a hash of 128 bit.

MD5是一个广泛使用的加密哈希函数,它产生的哈希值为128位。

In this article, we will see different approaches to create MD5 hashes using various Java libraries.

在这篇文章中,我们将看到使用各种Java库创建MD5哈希值的不同方法。

2. MD5 Using MessageDigest Class

2.使用MessageDigest类的MD5

There is a hashing functionality in java.security.MessageDigest class. The idea is to first instantiate MessageDigest with the kind of algorithm you want to use as an argument:

java.security.MessageDigest类中有一个hashing功能。我们的想法是,首先实例化MessageDigest,并将你想使用的算法作为参数。

MessageDigest.getInstance(String Algorithm)

And then keep on updating the message digest using update() function:

然后用update()函数继续更新消息摘要。

public void update(byte [] input)

The above function can be called multiple times when say you are reading a long file. Then finally we need to use digest() function to generate a hash code:

当你阅读一个长文件时,上述函数可以被多次调用。然后,最后我们需要使用digest()函数来生成一个哈希代码。

public byte[] digest()

Below is an example which generates a hash for a password and then verifies it:

下面是一个例子,它为一个密码生成一个哈希值,然后进行验证。

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

Similarly, we can also verify checksum of a file:

同样地,我们也可以验证文件的校验和。

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

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

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

3. MD5 Using Apache Commons

3.使用Apache Commons的MD5

The org.apache.commons.codec.digest.DigestUtils class makes things much simpler.

org.apache.commons.codec.digest.DigestUtils类使事情变得简单多了。

Let’s see an example for hashing and verifying password:

让我们看一个哈希和验证密码的例子。

@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 Using Guava

4.使用Guava的MD5

Below is another approach we can follow to generate MD5 checksums using com.google.common.io.Files.hash :

下面是另一种方法,我们可以使用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();
}

Note, that Hashing.md5 is deprecated. However, as the official documentation indicates, the reason is rather to advise not to use MD5 in general for security concerns. This means we can still use this method if we, for example, need to integrate with the legacy system that requires MD5. Otherwise, we’re better off considering safer options, like SHA-256.

请注意,Hashing.md5已被弃用。然而,正如官方文档所示,其原因是出于安全考虑,建议一般不要使用MD5。这意味着我们仍然可以使用这种方法,例如,如果我们需要与需要MD5的遗留系统集成。否则,我们最好考虑更安全的选项,比如SHA-256

5. Conclusion

5.结论

There are different ways in Java API and other third-party APIs like Apache commons and Guava to generate the MD5 hash. Choose wisely based on the requirements of the project and dependencies your project needs to follow.

在Java API和其他第三方API如Apache commons和Guava中有不同的方法来生成MD5哈希值。根据项目的要求和你的项目需要遵循的依赖性,明智地选择。

As always, the code is available over on Github.

像往常一样,代码可以在Github上获得