Bootstrap

Java实现SHA-1、SHA-256和SHA-512加密(原生摘要)

一、SHA简介

  安全散列算法(英语:Secure Hash Algorithm,缩写为SHA)是一个密码散列函数家族,是FIPS所认证的安全散列算法。能计算出一个数字消息所对应到的,长度固定的字符串(又称消息摘要)的算法。且若输入的消息不同,它们对应到不同字符串的机率很高。
  目前SHA有五个算法,分别是SHA-1SHA-224SHA-256SHA-384,和SHA-512,由美国安全局(NSA)所设计,并由美国国家标准与技术研究院(NIST)发布,也是美国的政府标准,后四者有时并称为SHA-2

二、SHA家族特点

SHA家族各个参数对比如下:

/SHA-1SHA-224SHA-256SHA-SHA-384SHA-512
消息摘要长度160224256384512
消息长度 2 64 2^{64} 264 2 64 2^{64} 264 2 64 2^{64} 264 2 128 2^{128} 2128 2 128 2^{128} 2128
字长度3232326464
分组长度51251251210241024
步骤数8064648080

三、SHA工具类

  工作中经常用的SHA的加密方法,比如SHA-1SHA-224SHA-256SHA-384SHA-512,总是分不清楚,让自己疑惑:是不是要写几个不同的工具类去实现?来,我告诉你!一个就够了,用Java原生摘要实现SHA的加密。

ShaUtil .java

package com.alian.csdn.utils;

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

/**
 * @program: CSDN
 * @description: SHA工具类
 * @author: Alian
 * @create: 2021-06-01 15:20:10
 **/
public class ShaUtil {

    private static final String SHA_1 = "SHA-1";
    private static final String SHA_224 = "SHA-224";
    private static final String SHA_256 = "SHA-256";
    private static final String SHA_384 = "SHA-384";
    private static final String SHA_512 = "SHA-512";

    private static final char[] hexDigits = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};

    public static String getSHA1(String painText, boolean uppercase) {
        return getSha(painText, SHA_1, uppercase);
    }

    public static String getSHA224(String painText, boolean uppercase) {
        return getSha(painText, SHA_224, uppercase);
    }

    public static String getSHA256(String painText, boolean uppercase) {
        return getSha(painText, SHA_256, uppercase);
    }

    public static String getSHA384(String painText, boolean uppercase) {
        return getSha(painText, SHA_384, uppercase);
    }

    public static String getSHA512(String painText, boolean uppercase) {
        return getSha(painText, SHA_512, uppercase);
    }

    /**
     * 利用Java原生摘要实现SHA加密(支持大小写,默认小写)
     *
     * @param plainText 要加密的数据
     * @param algorithm 要使用的算法(SHA-1,SHA-2224,SHA-256,SHA-384,SHA-512)
     * @param uppercase 是否转为大写
     * @return
     */
    private static String getSha(String plainText, String algorithm, boolean uppercase) {
        //输入的字符串转换成字节数组
        byte[] bytes = plainText.getBytes(StandardCharsets.UTF_8);
        MessageDigest messageDigest;
        try {
            //获得SHA转换器
            messageDigest = MessageDigest.getInstance(algorithm);
            //bytes是输入字符串转换得到的字节数组
            messageDigest.update(bytes);
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException("SHA签名过程中出现错误,算法异常");
        }
        //转换并返回结果,也是字节数组,包含16个元素
        byte[] digest = messageDigest.digest();
        //字符数组转换成字符串返回
        String result = byteArrayToHexString(digest);
        //转换大写
        return uppercase ? result.toUpperCase() : result;
    }

    /**
     * 将字节数组转为16进制字符串
     *
     * @param bytes 要转换的字节数组
     * @return
     */
    private static String byteArrayToHexString(byte[] bytes) {
        StringBuilder builder = new StringBuilder();
        for (byte b : bytes) {
            //java.lang.Integer.toHexString() 方法的参数是int(32位)类型,
            //如果输入一个byte(8位)类型的数字,这个方法会把这个数字的高24为也看作有效位,就会出现错误
            //如果使用& 0XFF操作,可以把高24位置0以避免这样错误
            String temp = Integer.toHexString(b & 0xFF);
            if (temp.length() == 1) {
                //1得到一位的进行补0操作
                builder.append("0");
            }
            builder.append(temp);
        }
        return builder.toString();
    }

}

四、实践

接下里我们对ShaUtil工具类进行一些测试,代码如下:

	/**
     * SHA计算(SHA-1,SHA-2224,SHA-256,SHA-384,SHA-512)
     * 此处单元测试的注解是采用:org.junit.Test
     */
    @Test
    public void sha() {
        String plainText="Alian";
        System.out.println("-----------------------------------SHA1-------------------------------------------------");
        System.out.println("小写的SHA1加密结果:"+ShaUtil.getSHA1(plainText,false));
        System.out.println("大写的SHA1加密结果:"+ShaUtil.getSHA1(plainText,true));
        System.out.println("-----------------------------------SHA224-----------------------------------------------");
        System.out.println("小写的SHA224加密结果:"+ShaUtil.getSHA224(plainText,false));
        System.out.println("大写的SHA224加密结果:"+ShaUtil.getSHA224(plainText,true));
        System.out.println("-----------------------------------SHA256-----------------------------------------------");
        System.out.println("小写的SHA256加密结果:"+ShaUtil.getSHA256(plainText,false));
        System.out.println("大写的SHA256加密结果:"+ShaUtil.getSHA256(plainText,true));
        System.out.println("-----------------------------------SHA384-----------------------------------------------");
        System.out.println("小写的SHA384加密结果:"+ShaUtil.getSHA384(plainText,false));
        System.out.println("大写的SHA384加密结果:"+ShaUtil.getSHA384(plainText,true));
        System.out.println("-----------------------------------SHA512-----------------------------------------------");
        System.out.println("小写的SHA512加密结果:"+ShaUtil.getSHA512(plainText,false));
        System.out.println("大写的SHA512加密结果:"+ShaUtil.getSHA512(plainText,true));
    }

运行结果:

-----------------------------------SHA1-------------------------------------------------
小写的SHA1加密结果:58800795a56cf404b5f67173c20dbc0a3eace5a6
大写的SHA1加密结果:58800795A56CF404B5F67173C20DBC0A3EACE5A6
-----------------------------------SHA224-----------------------------------------------
小写的SHA224加密结果:c2dc46888be174c2599aabd58e78177f3d2f4a795a7724fbed0b78f1
大写的SHA224加密结果:C2DC46888BE174C2599AABD58E78177F3D2F4A795A7724FBED0B78F1
-----------------------------------SHA256-----------------------------------------------
小写的SHA256加密结果:8c9781ffb256b431a5e38b9f7bd81df0c4bcbd0f835feb31126c4f5a7f4bb5e2
大写的SHA256加密结果:8C9781FFB256B431A5E38B9F7BD81DF0C4BCBD0F835FEB31126C4F5A7F4BB5E2
-----------------------------------SHA384-----------------------------------------------
小写的SHA384加密结果:9fbdf2441015cf0c8e49a49b3ce88fc0d508e33f8313dfa452239b4062b45a07df9938ebac3c7198353cf3aad18ae655
大写的SHA384加密结果:9FBDF2441015CF0C8E49A49B3CE88FC0D508E33F8313DFA452239B4062B45A07DF9938EBAC3C7198353CF3AAD18AE655
-----------------------------------SHA512-----------------------------------------------
小写的SHA512加密结果:2daf6197b540d862ce2c73edb14e3ff9e743724e3b96592a4cd71797ffe045b5a5d89865632e86ed338f2c534b4f698818fa670b7eae28dc493d1e1f4a455c89
大写的SHA512加密结果:2DAF6197B540D862CE2C73EDB14E3FF9E743724E3B96592A4CD71797FFE045B5A5D89865632E86ED338F2C534B4F698818FA670B7EAE28DC493D1E1F4A455C89

结语

以上就是今天要讲的内容,本文简单介绍了SHA,并编写了一个SHA工具类,有兴趣的同学可以去了解一下SHA算法的原理,因为安全性问题,平常的工作中尽量不使用SHA-1,改为SHA-256或者SHA-512或者采用其他安全性高的算法。如果觉得对你有帮助,欢迎大家评论交流。

;