天天看點

使用Java的MessageDigest實作MD5加密算法

文章目錄

  • 前言
  • 一、MessageDigest 類是什麼?
  • 二、方法介紹
    • 1、getInstance
    • 2、update
    • 3、digest
    • 4、reset
    • 5、isEqual
  • 三、使用步驟
    • 1.建立封包摘要執行個體
    • 2.傳入需要計算的字元串
    • 3.計算消息摘要
    • 4.處理計算結果
  • 四、MD5工具類
    • 1.MessageDigest實作對字元串的MD5加密算法
    • 2.MessageDigest實作對文本的MD5加密算法
    • 3.簡化寫法
  • 五、總結

前言

  金三銀四,又到了求職招聘旺季,很多粉絲也在此期間找到了工作,開始了自己項目實戰的首戰,最近有幾個粉絲小夥伴向我詢問MD5加密相關方面的問題,于是我寫下這篇部落格,希望能幫助到需要的人,作為參加工作即将滿一年的我,深知剛剛參加工作确實有很多需要學習的地方,一起加油~

一、MessageDigest 類是什麼?

  MessageDigest 類是一個引擎類,全類名是:認識java.security.MessageDigest ,是Java自帶的一個類,它是為了提供諸如 SHA1 或 MD5 等密碼上安全的封包摘要功能而設計的。密碼上安全的封包摘要可接受任意大小的輸入(一個位元組數組),并産生固定大小的輸出,該輸出稱為一個摘要或散列。摘要具有以下屬性:

1、無法通過計算找到兩個散列成相同值的封包。

2、摘要不反映任何與輸入有關的内容。

使用封包摘要可以生成資料唯一且可靠的辨別符。有時它們被稱為資料的“數字指紋”。

  傳回實作指定摘要算法的MessageDigest對象

/**
 * 傳回實作指定摘要算法的MessageDigest對象
 *
 * @param algorithm 請求的算法的名稱
 * @param provider 提供者名稱
 * @return MessageDigest 指定摘要算法的MessageDigest對象
 * @throws NoSuchAlgorithmException 當指定的請求算法名稱不存在時抛出異常
 */
public static MessageDigest getInstance(String algorithm) throws NoSuchAlgorithmException; 

/**
 * 傳回實作指定摘要算法的MessageDigest對象
 *
 * @param algorithm 請求算法的名稱
 * @return MessageDigest 指定摘要算法的MessageDigest對象
 * @throws NoSuchAlgorithmException 當指定的請求算法名稱不存在時抛出異常
 */
public static MessageDigest getInstance(String algorithm, String provider) throws NoSuchAlgorithmException, NoSuchProviderException;

           

  Provider可以通過java.security.Security的getProviders() 方法獲得已注冊的提供者清單

  SUN提供的常用的算法:

    MD2

    MD5

    SHA-1

    SHA-256

    SHA-384

    SHA-512

  MessageDigest對象在開始時會被初始化,對象通過調用update() 方法處理資料

/**
 * 使用指定的byte數組更新摘要
 *
 * @param input 指定的byte數組
 */
public void update(byte[] input);

           

  一旦所需要更新的資料都已經被更新後,應該調用digest() 方法完成Hash計算。

  對于給定數量的更新資料 ,digest() 方法隻能被調用一次.在調用digest() 方法之後,MessageDigest對象被重新設定成初始狀态。

/**
 * 通過執行諸如填充之類的最終操作完成Hash計算. 
 * 在調用此方法之後,摘要被重置
 *
 * @return byte[] Hash計算後的byte數組
 */
public byte[] digest();

           

  任何時候都可以調用reset() 方法重置摘要。

   比較兩個摘要的相等性.做簡單的位元組比較。

/**
 * 比較兩個摘要的相等性.做簡單的位元組比較
 *
 * @param digestA 比較的摘要位元組數組A
 * @param digestB 比較的摘要位元組數組B
 * @return boolean 是否相等
 */
public static boolean isEqual(byte[] digestA, byte[] digestB);

           

  計算摘要的第一步是建立封包摘要執行個體。像所有的引擎類一樣,擷取某類封包摘要算法的 MessageDigest 對象的途徑是調用 MessageDigest 類中的 getInstance 靜态 factory 方法:

public static MessageDigest getInstance(String algorithm)
           

  注意:算法名不區分大小寫。例如,以下所有調用都是相等的:

MessageDigest.getInstance("MD5") 
   MessageDigest.getInstance("md5")  
   MessageDigest.getInstance("Md5")
   MessageDigest.getInstance("mD5")
           

  調用程式可選擇指定提供者名稱,以保證所要求的算法是由已命名提供者實作的:

public static MessageDigest getInstance(String algorithm, String provider)
           

  調用 getInstance 将傳回已初始化過的封包摘要對象。是以,它不需要進一步的初始化。

m.update(x.getBytes(“UTF8” ));
           

  分析:x為需要計算的字元串,update傳入的參數是位元組類型或位元組類型數組,對于字元串,需要先使用getBytes( )方法生成字元串數組。

byte s[ ]=m.digest( );
           

StringBuffer buf = new StringBuffer("");
            for (int offset = 0; offset < b.length; offset++) {
                i = b[offset];
                if (i < 0)
                    i += 256;
                if (i < 16)
                    buf.append("0");
                buf.append(Integer.toHexString(i));
            }

            re_md5 = buf.toString();

        } catch (Exception e) {
            e.printStackTrace();
        }
           

/**
 * 将字元串轉換為MD5
 */
 public class ParseMD5 {
 	public static String parseStrToMd5L32(String str) {
 		// 将字元串轉換為32位小寫MD5 
 		String reStr = null;
 		try {
 			MessageDigest md5 = MessageDigest.getInstance("MD5");
 			byte[] bytes = md5.digest(str.getBytes());
 			StringBuffer stringBuffer = new StringBuffer();
 			for (byte b : bytes) {
 				int bt = b&0xff;
 				if (bt < 16) {
 					stringBuffer.append(0);
 				}
 				stringBuffer.append(Integer.toHexString(bt));
 			}
 			reStr = stringBuffer.toString();
 		} catch (NoSuchAlgorithmException e) {
 			e.printStackTrace();
 		}
 		return reStr;
 	}

	// 将字元串轉換為32位大寫的MD5
	public static String parseStrToMd5U32(String str) {
		String reStr = parseStrToMd5L32(str);
		if (reStr != null) {
			reStr = reStr.toUpperCase();
		}
		return resStr;
	}

	// 将字元串轉換為16位小寫的MD5
	public static String parseStrToMd5L16(String str) {
		String reStr = paseStrToMd5L32(str);
		if (reStr != null) {
			reStr = reStr.subString(8, 24);
		}
		return reStr;
	}

	// 将字元串轉換為16位大寫的MD5
	public static String parseStrToMd5U16(String str) {
		String reStr = parseStrToMd5L32(str);
		if (reStr != null) {
			reStr = reStr.toUpperCase().subString(8, 24);
		}
		return reStr;
	}
 }
           

public class MD5Util {
	// 将文本轉換為32位小寫的MD5
	public static String textToMd5L32(String plainText) {
		String result = null;
		// 判斷需要轉換的文本是否為空
		if (StringUtils.isBlank(plainText)) {
			return null;
		}
		try {
			// 進行執行個體化和初始化
			MessageDigest md5 = MessageDigest.getInstance("MD5");
			// 得到一個作業系統預設的位元組編碼格式的位元組數組
			byte[] byteInput = plainText.getBytes();
			// 對得到的位元組數組進行處理
			md5.update(byteInput);
			// 進行Hash計算并得到傳回結果
			byte[] btResult = md5.digest();
			// 得到進行Hash計算後資料的長度
			StringBuffer stringBuffer = new StringBuffer();
			for (byte b : btResult) {
				int bt = b&0xff;
				if (bt < 16) {
					stringBuffer.append(0);
				}
				stringBuffer.append(Integer.toHexString(bt));
			}
			reStr = stringBuffer.toString();
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		}
		return reStr;
	}

	// 将文本轉換為32位大寫的MD5
	public static String textToMd5U32(String plainText) {
		if (StringUtils.isBlank(plainText)) {
			return null;
		}
		String result = textToMd5L32(plainText);
		result = result.toUpperCase();
		return result;
	}	
}
           

public class MD5 {

    public static String encryption(String plainText1) {
        String plainText=plainText1+"1@boduojiayuan#$@";
        String re_md5 = new String();
        try {
           //  傳回實作指定摘要算法的MessageDigest對象
            MessageDigest md = MessageDigest.getInstance("MD5");
           //  對象通過調用update() 方法處理資料
            md.update(plainText.getBytes());
            // 調用digest() 方法完成Hash計算
            byte b[] = md.digest();
            int i;

            StringBuffer buf = new StringBuffer("");
            for (int offset = 0; offset < b.length; offset++) {
                i = b[offset];
                if (i < 0)
                    i += 256;
                if (i < 16)
                    buf.append("0");
                buf.append(Integer.toHexString(i));
            }
			// 将計算結果s轉換為字元串
            re_md5 = buf.toString();

        } catch (Exception e) {
            e.printStackTrace();
        }
        return re_md5;
    }