单向加密算法MD5和SHA

常用加密算法的Java实现
——单向加密算法MD5和SHA
1、Java 的安全体系架构
1.1             Java 的安全体系架构介绍
Java 中为安全 框架 提供类和 接口 JDK   安全  API   Java  编程语言的核心   API ,位于   java .security  包(及其子包),以及 sun.security API 包(及其子包)中。设计用于帮助开发人员在程序中同时使用低级和高级安全功能。
JDK 1.1  中第一次发布的  JDK  安全中引入了“ Java  加密 体系结构 ( JCA ) ,指的是用于访问和开发  Java  平台密码功能的构架。在  JDK 1.1  中, JCA  包括用于数字签名和 报文摘要  API JDK 1.2  大大扩展了  Java  加密体系结构,它还对证书管理基础结构进行了升级以支持   X.509  v3  证书,并为划分细致、可配置性强、功能灵活、可扩展的访问控制引入了新的  Java  安全 体系结构
Java  加密体系结构包含  JDK 1.2  安全  API  中与密码有关的部分,以及本文档中提供的一组约定和规范。为实现多重、可互操作的密码,它还提供了“提供者”体系结构。
Java  密码扩展   JCE ) )扩展了  JCA API ,包括用于加密、 密钥 交换和信息 认证码 MAC )的  API JCE   JDK  密码共同提供了一个与平台无关的完整密码  API JCE  作为  JDK  的扩展将独立发布,以符合美国的出口控制约束。
1.2  Eclipse 中关联 JDK 的源码
          为了更加深刻的理解单向加密算法 MD5 SHA 的在 Java 中的实现,可使用 Eclipse IDE 关联 JDK 的源码(笔者所用的是 JDK6.0 )。
JDK6.0 安装完成后在 JDK 的根目录( eg. C:\Java\jdk1.6.0_21 )有 src.zip 目录。可将该目录解压到另一个目录( eg. D:\amigo\study\ 技术随笔 \201405 )。 src.zip 中并不包含所有的 JDK 源代码,例如 sun 下面的子包都是不存在 src.zip 中的( eg.  本文使用的 sun.security 包及其子包就不在其中)。
          要想下载这些子包,需要下载 OpenJDK 的源代码, openjdk jdk 的开放原始码版本,以 GPL 协议的形式放出。在 JDK7 的时候, openjdk 已经成为 jdk7 的主干开   发, sun jdk7 是在 openjdk7 的基础上发布的,其大部分原始码都相同,只有少部分原始码被替换掉。使用 JRL(JavaResearch License Java 研究授权协议 ) 发布。
         OpenJDK 的下载地址: http://download.java.net/openjdk/jdk6/
          下载完毕后将解压后的 openjdk-6-src-b27-26_oct_2012\jdk\src\share\classes 目录下的所有的文件和文件夹拷贝到刚才解压的 src 目录下。
          接下来在 Eclipse 配置关联源码:点击“ Windows ->  Preferences ”,在左侧菜单选择“ Java -> Installed JREs ”,若已经配置本机的 JRE ,可以不用配置。若未配置,点击右侧的“ Add ”按钮,在弹出的“ Add JRE ”窗口选择安装的 JDK6.0 的路径( eg. C:\Java\jdk1.6.0_21 )。点击“ OK ”按钮完成 JRE 的设置。
          选中已设置的 JRE ,点击右侧的“ Edit… ”按钮,在弹出窗口中选择 rt.jar 包后,点击“ Source Attachment… ”按钮,在弹出的窗口中点击“ External Folder… ”按钮,将源码路径指向刚才 src 的路径( eg. D:\amigo\study\ 技术随笔 \201405 )。参见下图:
       

          点击“ OK ”按钮设置完成后,在其后编写 MD5 SHA 的实现时,在调用 MessageDigest 的相关方法的地方,可使用调试模式 F5 单步调试查看 Java MD5 SHA 单向加密算法实现主要涉及的类。
1.3 JDK MD5 SHA 加密的主要类
          JDK6.0 中,与 MD5 SHA 密切相关的几个类的类图如下:
      
       

          其中“ MessageDigestSpi ”为顶层抽象类,同一个包下的“ MessageDigest ”和“ DigestBase ”为子抽象类。
在上面的类图中,使用了 Delegate (委托)设计模式。这种模式的原理为类 B (在此处为 Delegage 内部类)和类 A (在此处为 MessageDigestSpi 类)是两个互相没有什么关系的类, B 具有和 A 一模一样的方法和属性;并且调用 B 中的方法和属性就是调用 A 中同名的方法和属性。 B 好像就是一个受 A 授权委托的中介。第三方的代码不需要知道 A 及其子类的存在,也不需要和 A 及其子类发生直接的联系,通过 B 就可以直接使用 A 的功能,这样既能够使用到 A 的各种功能,又能够很好的将 A 及其子类保护起来了。
         MD5 SHA 的相关代码都在 MD5 SHA 等类中,但是面向客户的 MessageDigest 抽象类不需要跟各个实现类打交道,只要通过委托类与其打交道即可。
2 MD5 加密
2.1  概述
Message Digest Algorithm MD5 (中文名为 消息摘要算法 第五版)为计算机安全领域广泛使用的一种散列函数,用以提供消息的完整性保护。该 算法 的文件号为 RFC 1321 R.Rivest,MIT Laboratory for Computer Science and RSA Data Security Inc. April 1992 .
MD5 的全称是 Message-Digest Algorithm 5 (信息 - 摘要算法),在 90 年代初由 MIT Laboratory for Computer Science RSA Data Security Inc Ronald L. Rivest 开发出来,经 MD2 MD3 MD4 发展而来。
MD5 用于确保信息传输完整一致。是计算机广泛使用的杂凑算法之一(又译 摘要算法 哈希算法 ),主流编程语言普遍已有 MD5 实现。将 数据 (如 汉字 )运算为另一固定长度值,是杂凑算法的基础原理, MD5 的前身有 MD2 MD3 MD4
MD5 的作用是让大容量信息在用 数字签名 软件签署私人 密钥 前被 " 压缩 " 成一种保密的格式(就是把一个任意长度的字节串变换成一定长的 十六进制 数字串)。
2.2  算法原理
MD5 算法简要的叙述可以为: MD5 512 位分组来处理输入的信息,且每一分组又被划分为 16 32 位子分组,经过了一系列的处理后,算法的输出由四个 32 位分组组成,将这四个 32 位分组级联后将生成一个 128 位散列值。
MD5 算法中,首先需要对信息进行填充,使其位长对 512 求余的结果等于 448 。因此,信息的位长( Bits Length )将被扩展至 N*512+448 N 为一个非负整数, N 可以是零。填充的方法如下,在信息的后面填充一个 1 和无数个 0 ,直到满足上面的条件时才停止用 0 对信息的填充。然后,在这个结果后面附加一个以 64 位二进制表示的填充前信息长度。经过这两步的处理,信息的位长 =N*512+448+64=(N+1 *512 ,即长度恰好是 512 的整数倍。这样做的原因是为满足后面处理中对信息长度的要求。
2.3 Java 中的 MD5 实现
         MD5 加密算法的 Java 实现如下所示:
package  amigo.endecrypt;

import  java.security.MessageDigest;

/** 
 * 采用MD5加密
 *  @author  Xingxing,Xie
 * @datetime 2014-5-31 
 */
public   class  MD5Util {
     /*** 
     * MD5加密 生成32位md5码
     *  @param  待加密字符串
     *  @return  返回32位md5码
     */
     public   static  String md5Encode(String inStr)  throws  Exception {
        MessageDigest md5 =  null ;
         try  {
            md5 = MessageDigest.getInstance("MD5");
        }  catch  (Exception e) {
            System.out.println(e.toString());
            e.printStackTrace();
             return  "";
        }

         byte [] byteArray = inStr.getBytes("UTF-8");
         byte [] md5Bytes = md5.digest(byteArray);
        StringBuffer hexValue =  new  StringBuffer();
         for  ( int  i = 0; i < md5Bytes.length; i++) {
             int  val = (( int ) md5Bytes[i]) & 0xff;
             if  (val < 16) {
                hexValue.append("0");
            }
            hexValue.append(Integer.toHexString(val));
        }
         return  hexValue.toString();
    }

     /**
     * 测试主函数
     *  @param  args
     *  @throws  Exception
     */
     public   static   void  main(String args[])  throws  Exception {
        String str =  new  String("amigoxiexiexingxing");
        System.out.println("原始:" + str);
        System.out.println("MD5后:" + md5Encode(str));
    }
}
    测试结果:
原始: amigoxiexiexingxing
MD5 后: e9ac094091b96b84cca48098bc21b1d6
 
3 SHA 加密
3.1  概述
SHA 是一种 数据加密算法 ,该算法经过加密专家多年来的发展和改进已日益完善,现在已成为公认的最安全的散列算法之一,并被广泛使用。该算法的思想是接收一段明文,然后以一种不可逆的方式将它转换成一段(通常更小)密文,也可以简单的理解为取一串输入码(称为预映射或信息),并把它们转化为长度较短、位数固定的输出序列即散列值(也称为信息摘要或信息认证代码)的过程。散列函数值可以说是对明文的一种 指纹 或是 摘要 所以对散列值的 数字签名 就可以视为对此明文的数字签名。
          安全散列算法 SHA Secure Hash Algorithm SHA) 是美国国家标准技术研究所发布的国家标准 FIPS PUB 180 ,最新的标准已经于 2008 年更新到 FIPS PUB 180-3 。其中规定了 SHA-1 SHA-224 SHA-256 SHA-384 ,和 SHA-512 这几种 单向散列算法 SHA-1 SHA-224 SHA-256 适用于长度不超过 2^64 二进制位的消息。 SHA-384 SHA-512 适用于长度不超过 2^128 二进制位的消息。
3.2  原理
SHA-1 是一种 数据加密算法 ,该算法的思想是接收一段明文,然后以一种不可逆的方式将它转换成一段(通常更小)密文,也可以简单的理解为取一串输入码(称为预映射或信息),并把它们转化为长度较短、位数固定的输出序列即散列值(也称为信息摘要或信息认证代码)的过程。
单向散列函数 的安全性在于其产生散列值的操作过程具有较强的单向性。如果在输入序列中嵌入密码,那么任何人在不知道密码的情况下都不能产生正确的散列值,从而保证了其安全性。 SHA 将输入流按照每块 512 位( 64 个字节)进行分块,并产生 20 个字节的被称为信息认证代码或信息摘要的输出。
该算法输入 报文 的长度不限,产生的输出是一个 160 位的 报文摘要 。输入是按 512  位的分组进行处理的。 SHA-1 是不可逆的、防冲突,并具有良好的雪崩效应。
通过散列算法可实现 数字签名 实现,数字签名的原理是将要传送的明文通过一种函数运算( Hash )转换成 报文摘要 (不同的明文对应不同的报文摘要),报文摘要加密后与明文一起传送给接受方,接受方将接受的明文产生新的报文摘要与发送方的发来报文摘要解密比较,比较结果一致表示明文未被改动,如果不一致表示明文已被篡改。
MAC  (信息认证代码)就是一个散列结果,其中部分输入信息是密码,只有知道这个密码的参与者才能再次计算和验证 MAC 码的合法性。
3.3 Java 中的 SHA 实现
         SHA 的在 Java 的实现与 MD5 类似,参考代码如下所示:
package  amigo.endecrypt;

import  java.security.MessageDigest;

/** 
 * 采用SHAA加密
 *  @author  Xingxing,Xie
 * @datetime 2014-6-1 
 */
public   class  SHAUtil {
     /*** 
     * SHA加密 生成40位SHA码
     *  @param  待加密字符串
     *  @return  返回40位SHA码
     */
     public   static  String shaEncode(String inStr)  throws  Exception {
        MessageDigest sha =  null ;
         try  {
            sha = MessageDigest.getInstance("SHA");
        }  catch  (Exception e) {
            System.out.println(e.toString());
            e.printStackTrace();
             return  "";
        }

         byte [] byteArray = inStr.getBytes("UTF-8");
         byte [] md5Bytes = sha.digest(byteArray);
        StringBuffer hexValue =  new  StringBuffer();
         for  ( int  i = 0; i < md5Bytes.length; i++) {
             int  val = (( int ) md5Bytes[i]) & 0xff;
             if  (val < 16) { 
                hexValue.append("0");
            }
            hexValue.append(Integer.toHexString(val));
        }
         return  hexValue.toString();
    }

     /**
     * 测试主函数
     *  @param  args
     *  @throws  Exception
     */
     public   static   void  main(String args[])  throws  Exception {
        String str =  new  String("amigoxiexiexingxing");
        System.out.println("原始:" + str);
        System.out.println("SHA后:" + shaEncode(str));
    }
}
     测试结果如下所示:
原始: amigoxiexiexingxing
SHA 后: 04f79f496dd6bdab3439511606528a4ad9caac5e
3 SHA-1 MD5 的比较
因为二者均由 MD4 导出, SHA-1 MD5 彼此很相似。相应的,他们的强度和其他特性也是相似,但还有以下几点不同:
1 )对强行攻击的安全性 :最显著和最重要的区别是 SHA-1 摘要比 MD5 摘要长 32  位。使用强行技术,产生任何一个 报文 使其摘要等于给定报摘要的难度对 MD5 2^128 数量级的操作,而对 SHA-1 则是 2^160 数量级的操作。这样, SHA-1 对强行攻击有更大的强度。
2 )对密码分析的安全性 :由于 MD5 的设计,易受密码分析的攻击, SHA-1 显得不易受这样的攻击。
3 )速度 :在相同的硬件上, SHA-1 的运行速度比 MD5 慢。
4 、参考文档
       MD5 加密 _ 百度百科》: http://baike.baidu.com/view/1039631.htm?fr=aladdin
       MD5_ 百度百科》: http://baike.baidu.com/view/7636.htm?fr=aladdin
MD5 解密网站》: http://www.cmd5.com/
SHA_ 百度百科》:
http://baike.baidu.com/link?url=FmqSdqu1CxQXDnQPxCD3hTdepu0RWV6N5dec5ZNWSC_U4WWle4a1h0E6744FnCRI
《加密解密在线测试网站》: http://tripledes.online-domain-tools.com/
Openjdk 下载地址: http://download.java.net/openjdk/jdk6/
OpenJDK JDK 的区别和联系》: http://blog.csdn.net/kiyoki/article/details/8777744

http://www.blogjava.net/amigoxie/archive/2014/06/01/414299.html
 

你可能感兴趣的:(java,javaWeb)