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

MessageDigest 通过其getInstance系列静态函数来进行实例化和初始化。MessageDigest 对象通过使用 update 方法处理数据。任何时候都可以调用 reset 方法重置摘要。一旦所有需要更新的数据都已经被更新了,应该调用 digest 方法之一完成哈希计算并返回结果。

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

MessageDigest 的实现可随意选择是否实现 Cloneable 接口。客户端应用程可以通过尝试复制和捕获 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 实例对象。
方法摘要
 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==

MessageDigest 详解相关推荐

  1. Android签名机制之---签名验证过程详解

    一.前言 今天是元旦,也是Single Dog的嚎叫之日,只能写博客来祛除寂寞了,今天我们继续来看一下Android中的签名机制的姊妹篇:Android中是如何验证一个Apk的签名.在前一篇文章中我们 ...

  2. 钉钉实现企业级微应用免登陆详解

    (一)基本概述: 钉钉中实现免登陆的核心思想就是通过corpId和corpSecret这两个参数来获得免登陆码Code,继而通过Code来获取用户信息,并在后台数据库中比对该用户信息是否存在,如果比对 ...

  3. 【java】JDK安全模块JCE核心Cipher使用详解

    1.概述 转载:JDK安全模块JCE核心Cipher使用详解 2.前提 javax.crypto.Cipher,翻译为密码,其实叫做密码器更加合适.Cipher是JCA(Java Cryptograp ...

  4. MD5单向散列算法详解

    历史: MD5 叫信息-摘要算法,是一种密码的算法,它可以对任何文件产生一个唯一的MD5验证码,每个文件的MD5码就如同每个人的指纹一样,都是不同的,这样,一旦这个文件在传输过程中,其内容被损坏或者被 ...

  5. Bitmap精炼详解第(三)节:Bitmap的压缩

    一,前期基础知识储备 笔者之前有两篇文章:<Bitmap精炼详解第(一)节:Bitmap解析和加载><Bitmap精炼详解第(二)节:Bitmap常见处理方式>解释了一些Bit ...

  6. 【Java网络编程与IO流】Java之Java Servlet详解

    Java网络编程与IO流目录: [Java网络编程与IO流]Java中IO流分为几种?字符流.字节流.缓冲流.输入流.输出流.节点流.处理流 [Java网络编程与IO流]计算机网络常见面试题高频核心考 ...

  7. 微信公众号开通步骤详解

    微信公众号开通步骤详解 微信服务验证 微信公众号接入第一步:开发URL指向的服务接口 开发接口 发布到外网能访问的服务 配置服务 设置白名单 微信服务验证 微信公众号接入第一步:开发URL指向的服务接 ...

  8. 常见的加密算法及详解都在这里!

    加密算法,是现在每个软件项目里必须用到的内容.广泛应用在包括了用户登入.数字签名.数据传输等多个场合.那大家都知道那些呢?今天我把常见的加密算法全部整理在这里,供大家学习参考. 首先,大家要知道加密算 ...

  9. Android Apk加壳技术实战详解

    前言 前几天面试了一家信息加密相关的公司,经过两轮面试原以为坐等HR,结果还有一个实践测试ORZ-面试这么多家公司,真心觉得这家公司很特殊,尤其是那个逻辑测试-算了,不扯远了,走回正题. 面试官加我Q ...

  10. 详解【负载均衡】(负载均衡算法、一致性hash、负载均衡架构分析)

    作者:duktig 博客:https://duktig.cn 优秀还努力.愿你付出甘之如饴,所得归于欢喜. 本文源码参看:https://github.com/duktig666/distribute ...

最新文章

  1. 暑期集训1:C++STL 例3:UVA-12100
  2. 解决UnicodeDecodeError: 'utf-8' codec can't decode byte 0xff in position 0: invalid start byte问题
  3. matlab讨论资金积累,资金积累、国民收入与人口增长的关系综合评估
  4. 科大星云诗社动态20210925
  5. 关于推荐和机器学习的几个网站
  6. 基于JAVA+SpringMVC+Mybatis+MYSQL的网上医院预约挂号系统
  7. Java中拦截器和过滤器的声明用途和区别
  8. java类中的static块_java类中static代码块的执行次数
  9. 提升交互设计必备的28本好书
  10. Django数据库的增删改查学习笔记
  11. 技术评审之技术文档的规范模板
  12. Flutter HotRealod详解
  13. 极智资讯 | 一文看尽今年的云栖大会 有哪些好玩的
  14. 一梦三四年——国产MOBA网游的巅峰
  15. 使用node实现向手机发送验证码
  16. HDU 6078 Wavel Sequence【动态规划】
  17. URL锚点HTML定位技术机制、应用与问题
  18. nvenc vs x264 对比(1)
  19. Linux兄弟连视频教程—B站评论区总结
  20. 出现Presentation Error的解决方法

热门文章

  1. gaussdb 安全维护【设置帐户权限】【02】
  2. 湘西州2021年高考成绩查询,2021年湘西高考状元名单公布,湘西文理科状元是谁多少分...
  3. excel数据库_EXCEL数据库DSUM DMAX DMIN DAVERAGE函数的用法
  4. 在线考试系统毕业设计设计过程及部分代码
  5. 微加速度计的原理与应用
  6. mysql批量导入csv数据_csv批量导入mysql命令
  7. CCS 软件使用经验四则
  8. UIControl详解
  9. Origin 2019b 图文安装教程及下载(附安装包)
  10. JavaScript高级程序设计知识点汇总