文章目錄
- 前言
- 一、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;
}