SHA加密演算法

大菠萝zZ發表於2024-09-14

SHA簡介

安全雜湊演算法(英語:Secure Hash Algorithm,縮寫為SHA)是一個密碼雜湊函式家族,是FIPS所認證的安全雜湊演算法。能計算出一個數字訊息所對應到的,長度固定的字串(又稱訊息摘要)的演算法。且若輸入的訊息不同,它們對應到不同字串的機率很高。
  目前SHA有五個演算法,分別是SHA-1、SHA-224、SHA-256、SHA-384,和SHA-512,由美國安全域性(NSA)所設計,並由美國國家標準與技術研究院(NIST)釋出,也是美國的政府標準,後四者有時並稱為SHA-2。

SHA家族特點

Sha-1 Sha-224 Sha-256 Sha-384 Sha-512
訊息摘要長度 160 224 256 384 512
訊息長度 264 264 264 264 2128
字長度 32 32 32 32 64
分組長度 512 512 512 1024 1024
步驟數 80 64 64 80 80

工具類

package com.dbl.util;

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

/**
 * @Author 高國鵬
 * @Create 2024/7/4 13:17
 * Description: SHA 系列演算法加密工具類
 */
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";

    public static String getSHA1(String str, boolean uppercase) {
        return getSHA(str, SHA_1, uppercase);
    }

    public static String getSHA224(String str, boolean uppercase) {
        return getSHA(str, SHA_224, uppercase);
    }

    public static String getSHA256(String str, boolean uppercase) {
        return getSHA(str, SHA_256, uppercase);
    }

    public static String getSHA384(String str, boolean uppercase) {
        return getSHA(str, SHA_384, uppercase);
    }

    public static String getSHA512(String str, boolean uppercase) {
        return getSHA(str, SHA_512, uppercase);
    }

    /**
     * 利用Java原生摘要實現SHA加密(支援大小寫,預設小寫)
     *
     * @param str       要加密的資料
     * @param algorithm 要使用的演算法(SHA-1,SHA-2224,SHA-256,SHA-384,SHA-512)
     * @param uppercase 是否轉為大寫
     * @return
     */
    private static String getSHA(String str, String algorithm, boolean uppercase) {
        byte[] bytes = str.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();
    }

}

相關文章