MessageDigest简单介绍
本文博客原文
參考文章:http://blog.sina.com.cn/s/blog_4f36423201000c1e.html 一、概述 java.security.MessageDigest類用于為應(yīng)用程序提供信息摘要算法的功能,如 MD5 或 SHA 算法。簡單點說就是用于生成散列碼。信息摘要是安全的單向哈希函數(shù),它接收隨意大小的數(shù)據(jù),輸出固定長度的哈希值。關(guān)于信息摘要和散列碼請參照《數(shù)字證書簡單介紹》MessageDigest?通過其getInstance系列靜態(tài)函數(shù)來進(jìn)行實例化和初始化。MessageDigest 對象通過使用?update?方法處理數(shù)據(jù)。不論什么時候都能夠調(diào)用?reset?方法重置摘要。一旦全部須要更新的數(shù)據(jù)都已經(jīng)被更新了,應(yīng)該調(diào)用?digest?方法之中的一個完畢哈希計算并返回結(jié)果。
對于給定數(shù)量的更新數(shù)據(jù),digest?方法僅僅能被調(diào)用一次。digest?方法被調(diào)用后,MessageDigest??對象被又一次設(shè)置成其初始狀態(tài)。
MessageDigest?的實現(xiàn)可任意選擇是否實現(xiàn) Cloneable 接口。client應(yīng)用程能夠通過嘗試復(fù)制和捕獲 CloneNotSupportedException 測試可復(fù)制性:
?MessageDigest md = MessageDigest.getInstance("SHA");
?try {
? ? ?md.update(toChapter1);
? ? ?MessageDigest tc1 = md.clone();
? ? ?byte[] toChapter1Digest = tc1.digest();
? ? ?md.update(toChapter2);
? ? ?...etc.
?} catch (CloneNotSupportedException cnse) {
? ? ?throw new DigestException("couldn't make digest of partial content");
?}
注意1:即時給定MessageDigest的實現(xiàn)是不可復(fù)制的,則仍然可以通過getInstance方法實例化幾個實例計算來同一時候進(jìn)行摘要信息的計算。
注意2:因為歷史原因,此類是抽象的,是從?MessageDigestSpi?擴(kuò)展的。應(yīng)用程序開發(fā)者僅僅應(yīng)該注意在此?MessageDigest?類中定義的方法;超類中的全部方法是供希望提供自己的信息摘要算法實現(xiàn)的加密服務(wù)提供者使用的。?
注意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();
? ? ? ? ? ? }
執(zhí)行結(jié)果
mdTemp1==mdTemp2?:false
mdTemp2==mdTemp3?:false
| protected | MessageDigest(String?algorithm)? ??????????創(chuàng)建具有指定算法名稱的MessageDigest?實例對象。 |
| ?Object | clone()? ??????????假設(shè)實現(xiàn)是可復(fù)制的,則返回一個副本。 |
| ?byte[] | digest()? ??????????通過運(yùn)行諸如填充之類的終于操作完畢哈希計算。 |
| ?byte[] | digest(byte[]?input)? ??????????使用指定的字節(jié)數(shù)組對摘要進(jìn)行最后更新,然后完畢摘要計算。 |
| ?int | digest(byte[]?buf, int?offset, int?len)? ??????????通過運(yùn)行諸如填充之類的終于操作完畢哈希計算。 |
| ?String | getAlgorithm()? ??????????返回標(biāo)識算法的獨(dú)立于實現(xiàn)細(xì)節(jié)的字符串。 |
| ?int | getDigestLength()? ??????????返回以字節(jié)為單位的摘要長度,假設(shè)提供程序不支持此操作而且實現(xiàn)是不可復(fù)制的,則返回 0。 |
| static?MessageDigest | getInstance(String?algorithm)? ??????????生成實現(xiàn)指定摘要算法的 MessageDigest 對象。 |
| static?MessageDigest | getInstance(String?algorithm,?Provider?provider)? ??????????生成實現(xiàn)指定提供程序提供的指定算法的 MessageDigest 對象,假設(shè)該算法可從指定的提供程序得到的話。 |
| static?MessageDigest | getInstance(String?algorithm,?String?provider)? ??????????生成實現(xiàn)指定提供程序提供的指定算法的 MessageDigest 對象,假設(shè)該算法可從指定的提供程序得到的話。 |
| ?Provider | getProvider()? ??????????返回此信息摘要對象的提供程序。 |
| static?boolean | isEqual(byte[]?digesta, byte[]?digestb)? ??????????比較兩個摘要的相等性。 |
| ?void | reset()? ??????????重置摘要以供再次使用。 |
| ?String | toString()? ??????????返回此信息摘要對象的字符串表示形式。 |
| ?void | update(byte?input)? ??????????使用指定的字節(jié)更新摘要。 |
| ?void | update(byte[]?input)? ??????????使用指定的字節(jié)數(shù)組更新摘要。 |
| ?void | update(byte[]?input, int?offset, int?len)? ??????????使用指定的字節(jié)數(shù)組,從指定的偏移量開始更新摘要。 |
| ?void | update(ByteBuffer?input)? ??????????使用指定的 ByteBuffer 更新摘要。 |
2.1、創(chuàng)建?MessageDigest?對象 計算信息摘(即散列碼)要做的第一步是創(chuàng)建?MessageDigest對象?實例。像全部的引擎類一樣,獲取某類報文摘要算法(即散列算法,比方MD5)的??MessageDigest?對象的途徑是調(diào)用?MessageDigest?類中的?getInstance?靜態(tài)?factory?方法:
? ? public static MessageDigest getInstance(String algorithm)
注意:算法名不區(qū)分大寫和小寫。比如,下面全部調(diào)用都是相等的: MessageDigest.getInstance("SHA");MessageDigest.getInstance("sha");MessageDigest.getInstance("sHa"); 調(diào)用程序可選擇指定提供者名稱,以保證所要求的算法是由已命名提供者實現(xiàn)的:public static MessageDigest getInstance(String algorithm, String provider);
調(diào)用 getInstance 將返回已初始化過的MessageDigest對象。因此,它不須要進(jìn)一步的初始化。 2.2、向MessageDigest傳送要計算的數(shù)據(jù) 計算數(shù)據(jù)的摘要的第二步是向已初始化的MessageDigest對象提供傳送要計算的數(shù)據(jù)。這將通過一次或多次調(diào)用下面某個?update(更新)方法來完畢: public void update(byte input);public void update(byte[] input);public void update(byte[] input, int offset, int len); 2.3、計算摘要 通過調(diào)用 update 方法向MessageDigest對象提傳送要計算的數(shù)據(jù)后,你就能夠調(diào)用下面某個 digest(摘要)方法來計算摘要(即生成散列碼): public byte[] digest();public byte[] digest(byte[] input);public int digest(byte[] buf, int offset, int len); 前兩個方法返回計算出的摘要。后一個方法把計算出的摘要儲存在所提供的 buf 緩沖區(qū)中,起點是 offset。len 是 buf 中分配給該摘要的字節(jié)數(shù)。該方法返回實際存儲在 buf 中的字節(jié)數(shù)。 對第二個接受輸入字節(jié)數(shù)組變量的 digest 方法的調(diào)用等價于用指定的輸入調(diào)用:? ? public void update(byte[] input)
,接著調(diào)用不帶參數(shù)的 digest 方法. 三、樣例演示 3.1、★ 編程思路: java.security包中的MessageDigest類提供了計算消息摘要(即生成散列碼)的方法,首先生成對象,運(yùn)行其update( )方法可 以將原始數(shù)據(jù)傳遞給該對象,然后運(yùn)行其digest( )方法就可以得到消息摘要。詳細(xì)過程例如以下: (1)生成MessageDigest對象MessageDigest m=MessageDigest.getInstance("MD5");
MessageDigest類也是一個工廠類,其構(gòu)造器是受保護(hù)的,不同意 直接使用new MessageDigist( )來創(chuàng)建對象,而必須通過其靜態(tài)方法getInstance( )生成MessageDigest對象。 當(dāng)中傳入的參數(shù)指定計算消息摘要所使用的算法,經(jīng)常使用的有"MD5","SHA"等。 (2)傳入須要計算的字符串m.update(x.getBytes("UTF8" ));
分析:x為須要計算的字符串,update傳入的參數(shù)是字節(jié)類型或字節(jié)類型數(shù)組,對于字符串,須要先使用getBytes( )方法生成字符串?dāng)?shù)組。 (3)計算消息摘要byte s[ ]=m.digest( );
分析:運(yùn)行MessageDigest對象的digest( )方法完畢計算,計算的結(jié)果通過字節(jié)類型的數(shù)組返回。 (4)處理計算結(jié)果 必要的話能夠使用例如以下代碼將計算結(jié)果(byte數(shù)組)轉(zhuǎn)換為字符串。 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.2、演示樣例一 ★完整程序例如以下: 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(); }} ★執(zhí)行結(jié)果900150983cd24fb0d6963f7d28e17f72
?3.3、演示樣例二 在這里我們將對計算生成的md5使用?sun.misc.BASE64Encoder進(jìn)行簡單的加密。 ? ? 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;? ? } 調(diào)用函數(shù) String str="0123456789"?System.out.println(md5sumWithEncoder(str)); 輸出 eB5eJF1ptWaXm4bijSPyxw== 3.4、演示樣例三 關(guān)于此請參考《一點關(guān)于計算MD5的封裝》轉(zhuǎn)載于:https://www.cnblogs.com/mengfanrong/p/3935308.html
總結(jié)
以上是生活随笔為你收集整理的MessageDigest简单介绍的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 数据结构之外部排序:归并排序法
- 下一篇: Oracle 查询字段在什么表