MessageDigest简单介绍

MessageDigest简单介绍本文博客原文參考文章:http://blog.sina.com.cn/s/blog_4f36423201000c1e.html一、概述java.security.MessageDigest类用于为应用

大家好,又见面了,我是你们的朋友全栈君。

本文博客原文

參考文章:
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?: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.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.net/154222.html原文链接:https://javaforall.net

赞 (0)
全栈程序员-站长的头像全栈程序员-站长

相关推荐

  • 2018年系统架构设计师上午真题

    2018年系统架构设计师上午真题●在磁盘调度管理中,应先进行移臂调度,再进行旋转调度。假设磁盘移动臂位于21号柱面上,进程的请求序列如下表所示。如果采用最短移臂调度算法,那么系统的响应序列应为( )。(1)A.②⑧③④⑤①⑦⑥⑨B.②③⑧④⑥⑨①⑤⑦C.①②③④⑤⑥⑦⑧⑨D.②⑧③⑤⑦①④⑥⑨●某计算机系统中的进程管理采用三态模型,那么下图所示的PCB(进程控制块)的组织方式采用( ),图中( )。…

    2022年6月1日
  • 【C/C++】C语言特性总结

    【C/C++】C语言特性总结已经有大约半年的时间没有碰C语言了,当时学习的时候记录了很多的笔记,但是都是特别混乱,后悔那个时候,不懂得写博客,这里凭借记忆和零零散散的笔记记录,尝试系统性地复习一下C语言。之前都是在Windows环境下学习,这次把重心放在Linux环境下,这次的复习源于基础,但是要高于基础。文章目录工具gcc编译器VS2019C语言编译过程C语言代码主体必要内容C语言数据类型关键字常量变量进制表示s…

    2022年6月21日
  • IP地址分类以及网络地址的计算(子网划分、超网划分)[通俗易懂]

    IP地址分类以及网络地址的计算(子网划分、超网划分)[通俗易懂]本次我将从以下5个方面介绍IP地址(由于篇幅的问题,本篇我只介绍分类编址,无分类编址将在下一篇介绍)了解IP地址的用途和种类 了解分类编址和无分类编址区别 掌握子网划分及超网划分方法 网络号与主机号的计算 掌握无分类编址的概念和使用1、IP地址的种类和用途IP用途:标记某个主机所在的位置种类:分类编址(早期设计,存在缺陷)和无分类编址(用来代替分类编制)2、分类编址…

    2022年4月26日
  • 基于Spring MVC + Spring + MyBatis的【超市会员管理系统】

    基于Spring MVC + Spring + MyBatis的【超市会员管理系统】文章目录一、**语言和环境**二、**实现功能**三、**数据库设计**四、**具体要求及推荐实现步骤**五、**实现代码**MySQL数据库:JAVA代码:一、语言和环境实现语言:JAVA语言。使用:MyEclipse/Eclipse+Tomcat+MySql。使用技术:Jsp+Servlet+JavaBean或SpringMVC+Spring+Mybatis。二、实现功能随着信息化时代系统管理的普及,城市中各个每一个超市的会员管理也需要与时.

    2022年6月23日
  • 数据结构中的elemtype、elem是什么

    数据结构中的elemtype、elem是什么ElemType是数据结构的书上为了说明问题而用的一个词。它是elementtype(“元素的类型”)的简化体。 因为数据结构是讨论抽象的数据结构和算法的,一种结构中元素的类型不一定是整型、字符型、浮点型或者用户自定义类型,为了不重复说明,使用过程中用“elemtype”代表所有可能的数据类型,简单明了的概括了整体。在算法中,除特别说明外,规定ElemType的默认是int型。elem是单词…

    2022年5月19日
  • 也说周鸿祎[通俗易懂]

    也说周鸿祎[通俗易懂]&#13; 最早听说周鸿祎是在林锐的《大学十年》的那篇妙文里。应该是2001年。第一次看完林锐的回忆,觉得这个家伙是个人物,可他居然对周鸿祎服贴得不得了,可见周的确不是一个一般人。没过多久,有媒体开始关注3721了。那个时候,3721还没到过街老鼠人人喊打的时候,一度攻城掠地,风管无限。记得3721最开始吸引眼球的就是和Realname的一场口水大战…

    2022年7月26日

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号