MessageDigest簡介(與MD5加密有關)

參考文章: http://blog.sina.com.cn/s/blog_4f36423201000c1e.html
參考來源:http://blog.csdn.net/hudashi/article/details/8394158
1、概述
java.security.MessageDigest類用於爲應用程序提供信息摘要算法的功能,如 MD5 或 SHA 算法。簡單點說就是用於生成散列碼。信息摘要是安全的單向哈希函數,它接收任意大小的數據,輸出固定長度的哈希值。關於信息摘要和散列碼請參照《 數字證書簡介

MessageDigest 經過其getInstance系列靜態函數來進行實例化和初始化。MessageDigest 對象經過使用 update 方法處理數據。任什麼時候候均可以調用 reset 方法重置摘要。一旦全部須要更新的數據都已經被更新了,應該調用 digest 方法之一完成哈希計算並返回結果。html

對於給定數量的更新數據,digest 方法只能被調用一次。digest 方法被調用後,MessageDigest  對象被從新設置成其初始狀態。java

MessageDigest 的實現可隨意選擇是否實現 Cloneable 接口。客戶端應用程能夠經過嘗試複製和捕獲 CloneNotSupportedException 測試可複製性:算法

 

 

 

 MessageDigest md = MessageDigest.getInstance("SHA");編程

 try {數組

     md.update(toChapter1);安全

     MessageDigest tc1 = md.clone();數據結構

     byte[] toChapter1Digest = tc1.digest();app

     md.update(toChapter2);ide

     ...etc.函數

 } catch (CloneNotSupportedException cnse) {

     throw new DigestException("couldn't make digest of partial content");

 }

注意1:即時給定MessageDigest的實現是不可複製的,則仍然可以經過getInstance方法實例化幾個實例計算來同時進行摘要信息的計算。

注意2:因爲歷史緣由,此類是抽象的,是從 MessageDigestSpi 擴展的。應用程序開發人員只應該注意在此 MessageDigest 類中定義的方法;超類中的全部方法是供但願提供本身的信息摘要算法實現的加密服務提供者使用的。 

注意3:MessageDigest並非單實例的。以下代碼所示:

 

 

 

       try

            {

                MessageDigest mdTemp1 = MessageDigest.getInstance("MD5");

                MessageDigest mdTemp2= MessageDigest.getInstance("MD5");

                MessageDigest mdTemp3= MessageDigest.getInstance("MD5");

                System.out.println("mdTemp1==mdTemp2?:"+(mdTemp1==mdTemp2));

                System.out.println("mdTemp2==mdTemp3?:"+(mdTemp2==mdTemp3));

            } catch (NoSuchAlgorithmException e)

            {

                // TODO Auto-generated catch block

                e.printStackTrace();

            }

運行結果

 

 

 

mdTemp1==mdTemp2?:false

mdTemp2==mdTemp3?:false

構造方法摘要
protected MessageDigest(String algorithm) 
          建立具備指定算法名稱的MessageDigest 實例對象。
 
方法摘要
 Object clone() 
          若是實現是可複製的,則返回一個副本。
 byte[] digest() 
          經過執行諸如填充之類的最終操做完成哈希計算。
 byte[] digest(byte[] input) 
          使用指定的字節數組對摘要進行最後更新,而後完成摘要計算。
 int digest(byte[] buf, int offset, int len) 
          經過執行諸如填充之類的最終操做完成哈希計算。
 String getAlgorithm() 
          返回標識算法的獨立於實現細節的字符串。
 int getDigestLength() 
          返回以字節爲單位的摘要長度,若是提供程序不支持此操做而且實現是不可複製的,則返回 0。
static MessageDigest getInstance(String algorithm) 
          生成實現指定摘要算法的 MessageDigest 對象。
static MessageDigest getInstance(String algorithm, Provider provider) 
          生成實現指定提供程序提供的指定算法的 MessageDigest 對象,若是該算法可從指定的提供程序獲得的話。
static MessageDigest getInstance(String algorithm, String provider) 
          生成實現指定提供程序提供的指定算法的 MessageDigest 對象,若是該算法可從指定的提供程序獲得的話。
 Provider getProvider() 
          返回此信息摘要對象的提供程序。
static boolean isEqual(byte[] digesta, byte[] digestb) 
          比較兩個摘要的相等性。
 void reset() 
          重置摘要以供再次使用。
 String toString() 
          返回此信息摘要對象的字符串表示形式。
 void update(byte input) 
          使用指定的字節更新摘要。
 void update(byte[] input) 
          使用指定的字節數組更新摘要。
 void update(byte[] input, int offset, int len) 
          使用指定的字節數組,從指定的偏移量開始更新摘要。
 void update(ByteBuffer input) 
          使用指定的 ByteBuffer 更新摘要。
2、實際實踐
2.一、建立 MessageDigest  對象
計算信息摘(即散列碼)要作的第一步是建立 MessageDigest對象 實例。像全部的引擎類同樣,獲取某類報文摘要算法(即散列算法,好比MD5)的  MessageDigest 對象的途徑是調用 MessageDigest 類中的 getInstance 靜態 factory 方法:

    public static MessageDigest getInstance(String algorithm)

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

 

MessageDigest.getInstance("SHA");
MessageDigest.getInstance("sha");
MessageDigest.getInstance("sHa");
調用程序可選擇指定提供者名稱,以保證所要求的算法是由已命名提供者實現的:

public static MessageDigest getInstance(String algorithm, String provider);

調用 getInstance 將返回已初始化過的MessageDigest對象。所以,它不須要進一步的初始化。
2.二、向MessageDigest 傳送要計算的數據
計算數據的摘要的第二步是向已初始化的MessageDigest對象提供傳送要計算的數據。這將經過一次或屢次調用如下某個 update(更新)方法來完成:

 

public void update(byte input);
public void update(byte[] input);
public void update(byte[] input, int offset, int len);
2.三、計算摘要
經過調用 update 方法向MessageDigest對象提傳送要計算的數據後,你就能夠調用如下某個 digest(摘要)方法來計算摘要(即生成散列碼):

 

public byte[] digest();
public byte[] digest(byte[] input);
public int digest(byte[] buf, int offset, int len);
前兩個方法返回計算出的摘要。後一個方法把計算出的摘要儲存在所提供的 buf 緩衝區中,起點是 offset。len 是 buf 中分配給該摘要的字節數。該方法返回實際存儲在 buf 中的字節數。
對第二個接受輸入字節數組變量的 digest 方法的調用等價於用指定的輸入調用:

    public void update(byte[] input)

,接着調用不帶參數的 digest 方法.
3、例子演示
3.1、★ 編程思路:
java.security包中的MessageDigest類提供了計算消息摘要(即生成散列碼)的方法,首先生成對象,執行其update( )方法可
以將原始數據傳遞給該對象,而後執行其digest( )方法便可獲得消息摘要。具體步驟以下:
(1)生成MessageDigest對象

MessageDigest m=MessageDigest.getInstance("MD5");

MessageDigest類也是一個工廠類,其構造器是受保護的,不容許
直接使用new MessageDigist( )來建立對象,而必須經過其靜態方法getInstance( )生成MessageDigest對象。
其中傳入的參數指定計算消息摘要所使用的算法,經常使用的有"MD5","SHA"等。
(2)傳入須要計算的字符串

m.update(x.getBytes("UTF8" ));

分析:x爲須要計算的字符串,update傳入的參數是字節類型或字節類型數組,對於字符串,須要先使用getBytes( )方法生成字符串數組。
(3)計算消息摘要

byte s[ ]=m.digest( );

分析:執行MessageDigest對象的digest( )方法完成計算,計算的結果經過字節類型的數組返回。
(4)處理計算結果
必要的話可使用以下代碼將計算結果(byte數組)轉換爲字符串。

 

static String convertToHexString(byte data[]) {
StringBuffer strBuffer = new StringBuffer();
for (int i = 0; i < data.length; i++) {
strBuffer.append(Integer.toHexString(0xff & data[i]));
}
return strBuffer.toString();
}
3.二、示例一
★完整程序以下:

 

public class MessageDigestDemo extends Thread {
public void run() {
String text = "abc";
byte data[] = null;
MessageDigest m;
try {
data = text.getBytes("UTF8");
m = MessageDigest.getInstance("MD5");
m.update(data);
byte resultData[] = m.digest();
System.out.println(convertToHexString(resultData));
} catch (NoSuchAlgorithmException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
 
}
 
static String convertToHexString(byte data[]) {
StringBuffer strBuffer = new StringBuffer();
for (int i = 0; i < data.length; i++) {
strBuffer.append(Integer.toHexString(0xff & data[i]));
}
return strBuffer.toString();
}
}
★運行結果

900150983cd24fb0d6963f7d28e17f72

 3.三、示例二
在這裏咱們將對計算生成的md5使用 sun.misc.BASE64Encoder進行簡單的加密。

 

    public String md5sumWithEncoder(String text) throws NoSuchAlgorithmException, 
UnsupportedEncodingException{
        /*肯定計算方法*/
        MessageDigest md5=MessageDigest.getInstance("MD5");
        BASE64Encoder base64en = new BASE64Encoder();
        /*加密後的散列碼字符串*/
        String strMd5=base64en.encode(md5.digest(text.getBytes("utf-8")));
        return strMd5;
    }
調用函數

 

String str="0123456789"
 System.out.printlnmd5sumWithEncoderstr));
 輸出
eB5eJF1ptWaXm4bijSPyxw==
3.四、示例三
關於此請參考《 一點關於計算MD5的封裝
相關文章
相關標籤/搜索