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

——单向加密算法MD5和SHA

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

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 包括用于数字签名和报文摘要的 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、MD3MD4

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

常用加密算法的Java实现(一)的更多相关文章

  1. 常用加密算法的Java实现总结

    常用加密算法的Java实现(一) ——单向加密算法MD5和SHA 1.Java的安全体系架构 1.1           Java的安全体系架构介绍 Java中为安全框架提供类和接口.JDK 安全 A ...

  2. 常用加密算法的Java实现总结(二)

    常用加密算法的Java实现总结(二) ——对称加密算法DES.3DES和AES 摘自:http://www.blogjava.net/amigoxie/archive/2014/07/06/41550 ...

  3. 常用加密算法的Java实现(一) ——单向加密算法MD5和SHA

    1.Java的安全体系架构 1.1           Java的安全体系架构介绍 Java中为安全框架提供类和接口.JDK 安全 API 是 Java 编程语言的核心 API,位于 java.sec ...

  4. 常用加密算法的Java实现总结(二) ——对称加密算法DES、3DES和AES

    1.对称加密算法 1.1 定义 对称加密算法是应用较早的加密算法,技术成熟.在对称加密算法中,数据发信方将明文(原始数据)和加密密钥(mi yue)一起经过特殊加密算法处理后,使其变成复杂的加密密文发 ...

  5. java常用加密算法

    常用加密算法的Java实现(一) ——单向加密算法MD5和SHA 日期:2014/6/1 文:阿蜜果 1.Java的安全体系架构 1.1           Java的安全体系架构介绍 Java中为安 ...

  6. 平时常用的一些java方法,请留意

    平时常用的一些java方法,请留意. package com.util; import java.io.BufferedInputStream; import java.io.BufferedWrit ...

  7. Java 常用正则表达式,Java正则表达式,Java身份证校验,最新手机号码正则表达式

    Java 常用正则表达式,Java正则表达式,Java身份证校验,最新手机号码校验正则表达式 ============================== ©Copyright 蕃薯耀 2017年11 ...

  8. SM4加密算法实现Java和C#相互加密解密

    SM4加密算法实现Java和C#相互加密解密 近期由于项目需要使用SM4对数据进行加密,然后传给Java后台,Java后台使用的也是SM4的加密算法但是就是解密不正确,经过一步步调试发现Java中好多 ...

  9. Memcached常用语法与java连接服务

    memcached常用语法及java使用方式 Author:SimpleWu Memcached 存储命令 Memcached set 命令用于将 value(数据值) 存储在指定的 key(键) 中 ...

随机推荐

  1. Oracle 删除重复数据的几种方法

    去重 第一种:distinct create table tmp_t3 as select distinct * from t3; drop table t3; alter table tmp_t2 ...

  2. 用efibootmgr管理UEFI启动项,添加丢失的启动项

    UEFI用来替代传统BIOS引导操作系统,学会修改UEFI启动项也变得十分重要,UEFI全称为:“统一的可扩展固件接口”(Unified Extensible Firmware Interface), ...

  3. 【 正确使用vim编辑器的姿势】

    vi:可视化接口(Visual Interface) vim:是vi的增强版(vi iMprove) vi编辑器是所有Unix及Linux系统下标准的编辑器,他就相当于windows系统中的记事本一样 ...

  4. Yeslab 华为安全HCIE七门之-防火墙基础(12篇)

    Yeslab 华为安全HCIE七门之-防火墙基础(12篇) Yeslab 全套华为安全HCIE七门之第二门防火墙基础(12篇),第一门课论坛很早就有了,可自行下载,后面的陆续分享给大家. 华为安全HC ...

  5. Mirai僵尸网络重出江湖

    近年数度感染数十万台路由器的僵尸网络程序Mirai,虽然原创者已经落网判刑,但是Mirai余孽却在网络上持续变种,现在安全人员发现,Mirai已经将焦点转向Linux服务器了. 安全公司Netcout ...

  6. LRJ入门经典-0903切蛋糕305

    原题 LRJ入门经典-0903切蛋糕305 难度级别:B: 运行时间限制:1000ms: 运行空间限制:256000KB: 代码长度限制:2000000B 试题描述 如图所示有一个矩形蛋糕,上面划分成 ...

  7. [Python] Execute a Python Script

    Python scripts can be executed by passing the script name to the python command or created as execut ...

  8. VS书签的应用

    为某一行添加书签,方便快速定位. 添加书签, 查找上一个书签, 查找下一个书签, 清空所有书签. 有意思.

  9. 57.NodeJS入门--环境搭建 IntelliJ IDEA

    转自:https://blog.csdn.net/wang19891106/article/details/51127133 NodeJS入门–环境搭建 IntelliJ IDEA 本人也刚开始学习N ...

  10. 给网站设置ICO图标

    方法一:         直接在站点根目录下放入名为:favicon.ico 的图标文件(必须要为 ICO 文件,BMP 及其他格式的图片文件不行).还有将 favicon.ico 中的 favico ...