posts - 297,  comments - 1618,  trackbacks - 0

常用加密算法的Java实现(一)

——单向加密算法MD5和SHA

日期:2014/6/1

文:阿蜜果

1、Java的安全体系架构

1.1           Java的安全体系架构介绍

Java中为安全框架提供类和接口JDK 安全 API Java 编程语言的核心 API,位于 java.security 包(及其子包),以及sun.securityAPI包(及其子包)中。设计用于帮助开发人员在程序中同时使用低级和高级安全功能。

JDK 1.1 中第一次发布的 JDK 安全中引入了“Java 加密体系结构(JCA),指的是用于访问和开发 Java 平台密码功能的构架。在 JDK 1.1 中,JCA 包括用于数字签名和报文摘要 APIJDK 1.2 大大扩展了 Java 加密体系结构,它还对证书管理基础结构进行了升级以支持 X.509 v3 证书,并为划分细致、可配置性强、功能灵活、可扩展的访问控制引入了新的 Java 安全体系结构

Java 加密体系结构包含 JDK 1.2 安全 API 中与密码有关的部分,以及本文档中提供的一组约定和规范。为实现多重、可互操作的密码,它还提供了“提供者”体系结构。

Java 密码扩展 JCE))扩展了 JCA API,包括用于加密、密钥交换和信息认证码MAC)的 APIJCE JDK 密码共同提供了一个与平台无关的完整密码 APIJCE 作为 JDK 的扩展将独立发布,以符合美国的出口控制约束。

1.2 Eclipse中关联JDK的源码

         为了更加深刻的理解单向加密算法MD5SHA的在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的源代码,openjdkjdk的开放原始码版本,以GPL协议的形式放出。在JDK7的时候,openjdk已经成为jdk7的主干开 发,sun jdk7是在openjdk7的基础上发布的,其大部分原始码都相同,只有少部分原始码被替换掉。使用JRL(JavaResearch LicenseJava研究授权协议)发布。

         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”按钮设置完成后,在其后编写MD5SHA的实现时,在调用MessageDigest的相关方法的地方,可使用调试模式F5单步调试查看JavaMD5SHA单向加密算法实现主要涉及的类。

1.3 JDKMD5SHA加密的主要类

         JDK6.0中,与MD5SHA密切相关的几个类的类图如下:
      
      

         其中“MessageDigestSpi”为顶层抽象类,同一个包下的“MessageDigest”和“DigestBase”为子抽象类。

在上面的类图中,使用了Delegate(委托)设计模式。这种模式的原理为类B(在此处为Delegage内部类)和类A(在此处为MessageDigestSpi类)是两个互相没有什么关系的类,B具有和A一模一样的方法和属性;并且调用B中的方法和属性就是调用A中同名的方法和属性。B好像就是一个受A授权委托的中介。第三方的代码不需要知道A及其子类的存在,也不需要和A及其子类发生直接的联系,通过B就可以直接使用A的功能,这样既能够使用到A的各种功能,又能够很好的将A及其子类保护起来了。

         MD5SHA的相关代码都在MD5SHA等类中,但是面向客户的MessageDigest抽象类不需要跟各个实现类打交道,只要通过委托类与其打交道即可。

2MD5加密

2.1 概述

Message Digest Algorithm MD5(中文名为消息摘要算法第五版)为计算机安全领域广泛使用的一种散列函数,用以提供消息的完整性保护。该算法的文件号为RFC 1321R.Rivest,MIT Laboratory for Computer Science and RSA Data Security Inc. April 1992.

MD5的全称是Message-Digest Algorithm 5(信息-摘要算法),在90年代初由MIT Laboratory for Computer ScienceRSA Data Security IncRonald L. Rivest开发出来,经MD2MD3MD4发展而来。

MD5用于确保信息传输完整一致。是计算机广泛使用的杂凑算法之一(又译摘要算法哈希算法),主流编程语言普遍已有MD5实现。将数据(如汉字)运算为另一固定长度值,是杂凑算法的基础原理,MD5的前身有MD2MD3MD4

MD5的作用是让大容量信息在用数字签名软件签署私人密钥前被"压缩"成一种保密的格式(就是把一个任意长度的字节串变换成一定长的十六进制数字串)。

2.2 算法原理

MD5算法简要的叙述可以为:MD5512位分组来处理输入的信息,且每一分组又被划分为1632位子分组,经过了一系列的处理后,算法的输出由四个32位分组组成,将这四个32位分组级联后将生成一个128位散列值。

MD5算法中,首先需要对信息进行填充,使其位长对512求余的结果等于448。因此,信息的位长(Bits Length)将被扩展至N*512+448N为一个非负整数,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

 

3SHA加密

3.1 概述

SHA是一种数据加密算法,该算法经过加密专家多年来的发展和改进已日益完善,现在已成为公认的最安全的散列算法之一,并被广泛使用。该算法的思想是接收一段明文,然后以一种不可逆的方式将它转换成一段(通常更小)密文,也可以简单的理解为取一串输入码(称为预映射或信息),并把它们转化为长度较短、位数固定的输出序列即散列值(也称为信息摘要或信息认证代码)的过程。散列函数值可以说是对明文的一种指纹或是摘要所以对散列值的数字签名就可以视为对此明文的数字签名。

         安全散列算法SHASecure Hash AlgorithmSHA)是美国国家标准技术研究所发布的国家标准FIPS PUB 180,最新的标准已经于2008年更新到FIPS PUB 180-3。其中规定了SHA-1SHA-224SHA-256SHA-384,和SHA-512这几种单向散列算法SHA-1SHA-224SHA-256适用于长度不超过2^64二进制位的消息。SHA-384SHA-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

3SHA-1MD5的比较

因为二者均由MD4导出,SHA-1MD5彼此很相似。相应的,他们的强度和其他特性也是相似,但还有以下几点不同:

1)对强行攻击的安全性:最显著和最重要的区别是SHA-1摘要比MD5摘要长32 位。使用强行技术,产生任何一个报文使其摘要等于给定报摘要的难度对MD52^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/

OpenJDKJDK的区别和联系》:http://blog.csdn.net/kiyoki/article/details/8777744

 

posted on 2014-06-01 17:13 阿蜜果 阅读(62340) 评论(7)  编辑  收藏 所属分类: Java


FeedBack:
# re: 常用加密算法的Java实现(一)
2014-06-01 19:11 | 手赚网-手机赚钱软件排行,手机赚钱平台,网络赚钱http://www.szapk.cn
手赚网-手机赚钱软件排行,手机赚钱平台,网络赚钱http://www.szapk.cn  回复  更多评论
  
# re: 常用加密算法的Java实现(一)
2014-06-01 22:43 | 李勇强
很好的加密算法 。。 收藏了  回复  更多评论
  
# re: 常用加密算法的Java实现(一)
2014-06-14 12:20 | 泡菜
文章写的实在是太好了,努力学习,一定能成功!  回复  更多评论
  
# re: 常用加密算法的Java实现(一)
2014-07-02 17:02 | 洛羽
从哪里可以对你加关注,为什么我没有找到?
菜鸟java程序员,新人求关照   回复  更多评论
  
# re: 常用加密算法的Java实现(一)
2014-07-05 18:15 | dsd
dasdasd  回复  更多评论
  
# re: 常用加密算法的Java实现(一)
2014-07-05 19:14 | dsd
<span style="color:red">飞碟</span>  回复  更多评论
  
# re: 常用加密算法的Java实现总结(一)——单向加密算法MD5和SHA
2015-12-03 17:14 | 魏励珊
中文md5加密有错  回复  更多评论
  

只有注册用户登录后才能发表评论。


网站导航:
 
<2014年6月>
25262728293031
1234567
891011121314
15161718192021
22232425262728
293012345

      生活将我们磨圆,是为了让我们滚得更远——“圆”来如此。
      我的作品:
      玩转Axure RP  (2015年12月出版)
      

      Power Designer系统分析与建模实战  (2015年7月出版)
      
     Struts2+Hibernate3+Spring2   (2010年5月出版)
     

留言簿(262)

随笔分类

随笔档案

文章分类

相册

关注blog

积分与排名

  • 积分 - 2286196
  • 排名 - 3

最新评论

阅读排行榜

评论排行榜