Java web

Java 实现 SHA

2020-04-09  本文已影响0人  又语

本文介绍 Java 语言实现 SHA Hash 的多种方法。


目录


SHA 简介

SHA(Secure Hash Algorithm,安全散列算法),至今为止共出现过 4 代。


实现方法

SHA 算法实现都比较相似,下面以 SHA-256 的实现为例,SHA-256 算法可以生成一个几乎唯一、固定 256 位(32 字节)的哈希值。
需要注意的是,因为 SHA3 在 2015 年才发布,因此直至 JDK 9 版本后才内置了此算法实现,本文未给出此算法实现示例。

基于 Java API
package tutorial.java.util;

import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

public class Sha256Utils {

    public static String sha256(String original) throws NoSuchAlgorithmException {
        MessageDigest messageDigest = MessageDigest.getInstance("SHA-256");
        byte[] hash = messageDigest.digest(original.getBytes(StandardCharsets.UTF_8));
        return bytesToHex(hash);
    }

    /**
     * 自定义字节到十六进制转换器来获取十六进制的哈希值
     */
    private static String bytesToHex(byte[] hash) {
        StringBuilder hexString = new StringBuilder();
        for (byte b : hash) {
            String hex = Integer.toHexString(0xff & b);
            if (hex.length() == 1) {
                hexString.append('0');
            }
            hexString.append(hex);
        }
        return hexString.toString();
    }
}
基于 Apache Commons
  1. 添加 Apache Commons Codec 依赖
<dependency>
    <groupId>commons-codec</groupId>
    <artifactId>commons-codec</artifactId>
    <version>1.14</version>
</dependency>
  1. 使用 org.apache.commons.codec.digest.DigestUtils 实现 SHA-256 Hash
package tutorial.java.util;

import org.apache.commons.codec.digest.DigestUtils;

public class Sha256Utils {

    public static String sha256(String original) {
        return DigestUtils.sha256Hex(original);
    }
}
基于 Google Guava
  1. 添加 Google Guava 依赖
<dependency>
    <groupId>com.google.guava</groupId>
    <artifactId>guava</artifactId>
    <version>28.2-jre</version>
</dependency>

使用 com.google.common.hash.Hashing 实现 SHA-256 Hash

package tutorial.java.util;

import com.google.common.hash.Hashing;

import java.nio.charset.StandardCharsets;

public class Sha256Utils {

    public static String sha256(String original) {
        return Hashing.sha256()
                .hashString(original, StandardCharsets.UTF_8)
                .toString();
    }
}
基于 Bouncy Castle
  1. 添加 Bouncy Castle 依赖
<dependency>
    <groupId>org.bouncycastle</groupId>
    <artifactId>bcprov-jdk15on</artifactId>
    <version>1.65</version>
</dependency>
  1. 同 Java API 类似,只是最后一步将字节转换为十六进制使用了 org.bouncycastle.util.encoders.Hex 实现。
package tutorial.java.util;

import org.bouncycastle.util.encoders.Hex;

import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

public class Sha256Utils {

    public static String sha256(String original) throws NoSuchAlgorithmException {
        MessageDigest digest = MessageDigest.getInstance("SHA-256");
        byte[] hash = digest.digest(original.getBytes(StandardCharsets.UTF_8));
        return new String(Hex.encode(hash));
    }
}
单元测试

适用于以上所有示例代码。

package tutorial.java.util;

import org.junit.Assert;
import org.junit.Test;

import java.security.NoSuchAlgorithmException;

public class Sha256UtilsTest {

    @Test
    public void testSha256() throws NoSuchAlgorithmException {
        String original = "ABCDEFG";
        String expected = "e9a92a2ed0d53732ac13b031a27b071814231c8633c9f41844ccba884d482b16";
        Assert.assertEquals(expected, Sha256Utils.sha256(original));
    }
}
上一篇下一篇

猜你喜欢

热点阅读