java MD5(Message Digest Algorithm 5)加密算法

本文介绍了MD5加密算法的原理和Java中如何利用`java.security.MessageDigest`进行加密。MD5是一种广泛用于数据安全的哈希算法,尽管存在破解风险,但在普通数据传输中仍可提供一定程度的安全保障。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在工作项目中,我们接受用户的个人信息和类似账号密码此类数据时必须对其进行加密,否则可能会导致信息的泄露引发安全性问题。加密的方式有很多种,其中较为常用的加密方式是MD5加密算法和SHA-1加密算法,这两种算法中MD5较为常用。MD5用于确保信息传输完整一致,是一种计算机广泛使用的哈希算法,主流编程语言普遍已有MD5实现。

MD5算法

MD5是一种通过固定的算法将任意位长的数据转化为固定长度128位(16字节)长的加密算法。这种算法容易计算,从原数据得到MD5值是很容易操作的。而且对于极其相似两个的原数据,即使相差只有一位,最后得到的MD5加密结果都是有很大区别的。而且MD5具有很强的抗碰撞性,即使已知原数据和MD5的值想找到一个具有相同的MD5值的伪造数据也很困难。

但是随着MD5算法被破解,通过杂凑算法伪造数据的可能性也是有的。但这并不妨碍我们在电子商务领域对MD5算法的使用,只是当需要传输安全性要求极高的数据时需要采用加密程度更高、安全性更好的加密算法。普通的数据传输及个人信息和类似账号密码传输都可以使用MD5加密算法。

MD5算法加密原理

在进行JAVA实现前,我们有必要先了解MD5算法加密的原理,因为我们的目的并不是专门研究密码领域,所以这里仅简要的表述算法加密的原理,为我们使用java来实现加密做铺垫。

1.填充并处理原数据

MD5加密算法会将任意长度的数据转换为128位字串。在进行加密前的第一步要做的事将数据填充至512位(512位是四个128位)长度的倍数。无论数据是否是512位的倍数,我们都将其进行填充,直到总长度为:N*512+448为止。在数据的后面先添加一个1,再添加若干个0知道符合上述长度为止。在这个结果后面再添上64数据,表示填充之前的数据的长度,如果数据位数太多,则采用低64位。

经过如此处理,我们得到了N*512+448+64位的数据,一共有(N+1)*512个数据。

2.将变量进行初始化并分组

初始的128位值为初试链接变量,由128=32*4分为4组32位的数据。用大端法表示这些数据。第一分组需要将上面四个链接变量复制到另外四个变量中:A到a,B到b,C到c,D到d。从第二分组开始的变量为上一分组的运算结果,即A = a, B = b, C = c, D = d。每一组都是如此操作。

3.MD5加密算法

主循环有四轮操作,每轮循环的算法都几乎相同。第一轮进行16次操作。每次操作对a、b、c和d中的其中三个作一次非线性函数运算,然后将所得结果加上第四个变量,文本的一个子分组和一个常数。再将所得结果向左环移一个不定的数,并加上a、b、c或d中之一。最后用该结果取代a、b、c或d中之一。我们不必过于纠结具体的算法,我们在代码实现时这些算法已经被封装好。

四个非线性函数:
F( X ,Y ,Z ) = ( X & Y ) | ( (~X) & Z )
G( X ,Y ,Z ) = ( X & Z ) | ( Y & (~Z) )
H( X ,Y ,Z ) =X ^ Y ^ Z
I( X ,Y ,Z ) =Y ^ ( X | (~Z) )

4.输出最后加密结果

最后将MD5算法加密后的a、b、c和d的级联作为整个算法的输出值。

java.security.MessageDigest

很多的项目中,我们用整个辅助类或是自己编写的util类来实现MD5的效果。实际上在java中有MD5的这个类,在security包中,名字就是MessageDigest。此 MessageDigest 类为应用程序提供信息摘要算法的功能,如 MD5 或 SHA 算法。

MessageDigest类使用步骤:

  1. 初始化MessageDigest对象
  2. 调用update方法传入要进行加密的byte数据
  3. (可选)调用reset方法重置要传入进行加密的数据
  4. 调用digest方法对传入的数据进行加密
package MD5;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

public class mda5 {

    public static void main(String[] args) {
        // TODO Auto-generated method stub

        String strData = "words";
        String strMD5 = null;

        try {

            MessageDigest md5 = MessageDigest.getInstance("MD5");
            md5.update(strData.getBytes());
            // md5.reset();
            if (strData == null || "".equals(strData))
                strMD5 = null;
            else {
                byte[] mdBytes = md5.digest();
                StringBuffer sb = new StringBuffer();
                for(int i = 0 ;i<mdBytes.length;i++){
                    int bt = mdBytes[i]&0xff;  
                    if (bt < 16){  
                        sb.append(0);  
                    }   
                    sb.append(Integer.toHexString(bt));  
                }
                strMD5 = sb.toString(); 
            }

        } catch (NoSuchAlgorithmException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }

}

在项目中使用的一个实战例子

在我最近工作的项目中也有用到MD5加密的工具类,简洁易懂,在这里分享一下,可以用来备份拷贝。

package com.framework.util;

import java.security.MessageDigest;

/**
 * 
 * @author Quinn
 *
 */
public class MD5Util {

    /**
     * The MD5 encryption operation is performed on the incoming information.
     * 
     * @param origin
     *            Enter the information to be encrypted.
     * @param charsetname
     *            Byte code type.
     * @return Display MD5 encryption results in lower case letters and numbers.
     */
    public static String MD5Encode(String origin, String charsetname) {
        String resultString = null;
        byte[] b = null;
        try {
            resultString = new String(origin);
            MessageDigest md = MessageDigest.getInstance("MD5");
            if (charsetname == null || "".equals(charsetname))
                b = md.digest(resultString.getBytes());
            else
                b = md.digest(resultString.getBytes(charsetname));
            StringBuffer resultSb = new StringBuffer();
            for (byte bs : b) {
                int bt = bs & 0xff;
                if (bt < 16)
                    resultSb.append(0);
                resultSb.append(Integer.toHexString(bt));
            }
            resultString = resultSb.toString().toLowerCase();
        } catch (Exception exception) {
            exception.printStackTrace();
        }
        return resultString;
    }

    /**
     * The MD5 encryption operation is performed on the incoming information and
     * return upper case letters and numbers.
     * 
     * @param origin
     *            Enter the information to be encrypted.
     * @param charsetname
     *            Byte code type.
     * @return Display MD5 encryption results in upper case letters and numbers.
     */
    public static String MD5EncodeUpper(String origin, String charsetname) {
        String resultString = MD5Encode(origin, charsetname);
        if (resultString != null)
            resultString = resultString.toUpperCase();
        return resultString;
    }

}
MD5的全称是Message-Digest Algorithm 5(信息-摘要算法),在90年代初由MIT Laboratory for Computer Science和RSA Data Security Inc的Ronald L. Rivest开发出来,经MD2、MD3和MD4发展而来。它的作用是让大容量信息在用数字签名软件签署私人密匙前被"压缩"成一种保密的格式(就是把一个任意长度的字节串变换成一定长的大整数)。不管是MD2、MD4还是MD5,它们都需要获得一个随机长度的信息并产生一个128位的信息摘要。虽然这些算法的结构或多或少有些相似,但MD2的设计与MD4和MD5完全不同,那是因为MD2是为8位机器做过设计优化的,而MD4和MD5却是面向32位的电脑。这三个算法的描述和C语言源代码在Internet RFCs 1321中有详细的描述(http://www.ietf.org/rfc/rfc1321.txt),这是一份最权威的文档,由Ronald L. Rivest在1992年8月向IEFT提交。   Rivest在1989年开发出MD2算法。在这个算法中,首先对信息进行数据补位,使信息的字节长度是16的倍数。然后,以一个16位的检验和追加到信息末尾。并且根据这个新产生的信息计算出散列值。后来,Rogier和Chauvaud发现如果忽略了检验和将产生MD2冲突。MD2算法加密后结果是唯一的--既没有重复。   为了加强算法的安全性,Rivest在1990年又开发出MD4算法MD4算法同样需要填补信息以确保信息的字节长度加上448后能被512整除(信息字节长度mod 512 = 448)。然后,一个以64位二进制表示的信息的最初长度被添加进来。信息被处理成512位Damg?rd/Merkle迭代结构的区块,而且每个区块要通过三个不同步骤的处理。Den Boer和Bosselaers以及其他人很快的发现了攻击MD4版本中第一步和第三步的漏洞。Dobbertin向大家演示了如何利用一部普通的个人电脑在几分钟内找到MD4完整版本中的冲突(这个冲突实际上是一种漏洞,它将导致对不同的内容进行加密却可能得到相同的加密后结果)。毫无疑问,MD4就此被淘汰掉了。   尽管MD4算法在安全上有个这么大的漏洞,但它对在其后才被开发出来的好几种信息安全加密算法的出现却有着不可忽视的引导作用。除了MD5以外,其中比较有名的还有SHA-1、RIPE-MD以及HAVAL等。   一年以后,即1991年,Rivest开发出技术上更为趋近成熟的MD5算法。它在MD4的基础上增加了"安全-带子"(Safety-Belts)的概念。虽然MD5MD4稍微慢一些,但却更为安全。这个算法很明显的由四个和MD4设计有少许不同的步骤组成。在MD5算法中,信息-摘要的大小和填充的必要条件与MD4完全相同。Den Boer和Bosselaers曾发现MD5算法中的假冲突(Pseudo-Collisions),但除此之外就没有其他被发现的加密后结果了。   Van Oorschot和Wiener曾经考虑过一个在散列中暴力搜寻冲突的函数(Brute-Force Hash Function),而且他们猜测一个被设计专门用来搜索MD5冲突的机器(这台机器在1994年的制造成本大约是一百万美元)可以平均每24天就找到一个冲突。但单从1991年到2001年这10年间,竟没有出现替代MD5算法MD6或被叫做其他什么名字的新算法这一点,我们就可以看出这个瑕疵并没有太多的影响MD5的安全性。上面所有这些都不足以成为MD5的在实际应用中的问题。并且,由于MD5算法的使用不需要支付任何版权费用的,所以在一般的情况下(非绝密应用领域。但即便是应用在绝密领域内,MD5也不失为一种非常优秀的中间技术),MD5怎么都应该算得上是非常安全的了。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值