MessageDigest简单介绍

一、概述

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

二、实际实践

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==

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小虾仁芜湖

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值