博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
MessageDigest简单介绍
阅读量:4548 次
发布时间:2019-06-08

本文共 5766 字,大约阅读时间需要 19 分钟。

本文博客

參考文章:
一、概述
java.security.
MessageDigest
类用于为应用程序提供信息摘要算法的功能,如 MD5 或 SHA 算法。简单点说就是用于生成
散列码
信息摘要是安全的单向哈希函数,它接收随意大小的数据,输出固定长度的哈希值。关于
信息摘要
散列码
请參照《

MessageDigest 通过其getInstance系列静态函数来进行实例化和初始化。MessageDigest 对象通过使用  方法处理数据。不论什么时候都能够调用  方法重置摘要。一旦全部须要更新的数据都已经被更新了,应该调用  方法之中的一个完毕哈希计算并返回结果。

对于给定数量的更新数据,digest 方法仅仅能被调用一次。digest 方法被调用后,MessageDigest  对象被又一次设置成其初始状态。

MessageDigest 的实现可任意选择是否实现 Cloneable 接口。client应用程能够通过尝试复制和捕获 CloneNotSupportedException 測试可复制性:

 

 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的实现是不可复制的,则仍然可以通过getInstance方法实例化几个实例计算来同一时候进行摘要信息的计算。

注意2:因为历史原因,此类是抽象的,是从 MessageDigestSpi 扩展的。应用程序开发者仅仅应该注意在此 MessageDigest 类中定义的方法;超类中的全部方法是供希望提供自己的信息摘要算法实现的加密服务提供者使用的。 

注意3MessageDigest并非单实例的。例如以下代码所看到的:

 

       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 ( algorithm) 
          创建具有指定算法名称的MessageDigest 实例对象
 
方法摘要
  () 
          假设实现是可复制的,则返回一个副本。
 byte[] () 
          通过运行诸如填充之类的终于操作完毕哈希计算。
 byte[] (byte[] input) 
          使用指定的字节数组对摘要进行最后更新,然后完毕摘要计算。
 int (byte[] buf, int offset, int len) 
          通过运行诸如填充之类的终于操作完毕哈希计算。
  () 
          返回标识算法的独立于实现细节的字符串。
 int () 
          返回以字节为单位的摘要长度,假设提供程序不支持此操作而且实现是不可复制的,则返回 0。
static  ( algorithm) 
          生成实现指定摘要算法的 MessageDigest 对象。
static  ( algorithm,  provider) 
          生成实现指定提供程序提供的指定算法的 MessageDigest 对象,假设该算法可从指定的提供程序得到的话。
static  ( algorithm,  provider) 
          生成实现指定提供程序提供的指定算法的 MessageDigest 对象,假设该算法可从指定的提供程序得到的话。
  () 
          返回此信息摘要对象的提供程序。
static boolean (byte[] digesta, byte[] digestb) 
          比較两个摘要的相等性。
 void () 
          重置摘要以供再次使用。
  () 
          返回此信息摘要对象的字符串表示形式。
 void (byte input) 
          使用指定的字节更新摘要。
 void (byte[] input) 
          使用指定的字节数组更新摘要。
 void (byte[] input, int offset, int len) 
          使用指定的字节数组,从指定的偏移量開始更新摘要。
 void ( input) 
          使用指定的 ByteBuffer 更新摘要。
二、实际实践
2.1、创建 
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.2、向
MessageDigest
传送要计算的数据
计算数据的摘要的第二步是向已初始化的
MessageDigest对象提供传送要计算的数据。这将通过一次或多次调用下面某个 
update(更新)方法来完毕:
 

public
void
update
(
byte
input
);
public
void
update
(
byte
[]
input
);
public
void
update
(
byte
[]
input
,
int
offset
,
int
len
);

2.3、计算摘要
通过调用 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.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.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
();
}
}

★执行结果
 

900150983cd24fb0d6963f7d28e17f72

 3.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
.
println
md5sumWithEncoder
str
));

 输出
eB5eJF1ptWaXm4bijSPyxw==
3.4、演示样例三
关于此请參考《

转载于:https://www.cnblogs.com/mengfanrong/p/3896447.html

你可能感兴趣的文章
ckplayer-超酷网页视频播放器的使用
查看>>
35+多用途WordPress主题
查看>>
KVO实现原理
查看>>
a:link,a:visited,a:hover,a:active
查看>>
DTD与XML的关系
查看>>
ASP.NET Development Server使用方法
查看>>
服务器运维基础指南
查看>>
读后感
查看>>
使用Crypto对数据进行加密解密
查看>>
CSS五類常用選擇器(收藏)
查看>>
have a thing用法
查看>>
为什么 远程钩子 必须使用动态链接库dll(而且是.data? 段共享的动态链接库)...
查看>>
redis 从0到1 linux下的安装使用 数据类型 以及操作指令 一
查看>>
MongoDB-启动的时候出现了问题
查看>>
解决nginx: [error] open() "/usr/local/nginx/logs/nginx.pid" failed错误
查看>>
第三次作
查看>>
模板 - ST表
查看>>
ZMQ示例:使用 curve 进行加密通信
查看>>
【网络流】 SGU 194 Reactor Cooling 无源无汇上下界可行流(裸题)
查看>>
cmd命令大全
查看>>