大家好,又见面了,我是全栈君,祝每个程序员都可以多学几门语言。
本文博客原文
參考文章: http://blog.sina.com.cn/s/blog_4f36423201000c1e.html
一、概述
java.security. MessageDigest 类用于为应用程序提供信息摘要算法的功能,如 MD5 或 SHA 算法。简单点说就是用于生成散列码。 信息摘要是安全的单向哈希函数,它接收随意大小的数据,输出固定长度的哈希值。关于信息摘要 和散列码请參照《数字证书简单介绍》
MessageDigest 通过其getInstance系列静态函数来进行实例化和初始化。MessageDigest 对象通过使用 update
方法处理数据。不论什么时候都能够调用 reset
方法重置摘要。一旦全部须要更新的数据都已经被更新了,应该调用 digest
方法之中的一个完毕哈希计算并返回结果。
对于给定数量的更新数据,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
类中定义的方法;超类中的全部方法是供希望提供自己的信息摘要算法实现的加密服务提供者使用的。
注意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?:falsemdTemp2==mdTemp3?:false
构造方法摘要 | |
---|---|
protected | MessageDigest(String algorithm) 创建具有指定算法名称的MessageDigest 实例对象。 |
二、实际实践
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、演示样例三
关于此请參考《 一点关于计算MD5的封装 》
发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/118454.html原文链接:https://javaforall.cn