MD5算法原理及其实现

1、  什么是MD5?
MD5(单项散列算法)
全名MessageDigest Algorithm 5 ,中文名为消息摘要算法第五版,通过特定的hash散列算法,讲文本信息转换成简短的信息摘要(压缩+加密+hash算法),是绝对不可逆的。

2、  MD5的安全性
[MD5的两个基本属性]
1)两个不同的报文难以生成相同的摘要
2)难以对制定的摘要生成一个报文,而可以由改报文反推算出改指定的摘要
简而言之:从不同报文生成不同摘要,不能从摘要推算出报文(不可逆)
所以,如果是安全级别一般的系统要求,可以用MD5进行加密,而且MD5的使用不需要支付任何版权费用,但是,实际上如果把用户的密码MD5处理后再存储到数据库,其实是很不安全的。因为用户的密码是比较短的,而且很多用户的密码都使用生日,手机号码,身份证号码,电话号码等等。或者使用常用的一些吉利的数字,或者某个英文单词。如果我把常用的密码先MD5处理,把数据存储起来,然后再跟你的MD5结果匹配,这时我就有可能得到明文。比如某个MD5破解网站http://www.cmd5.com/default.aspx 就可以根据密文推出相应的原文.

3、  MD5的代码实现
1)简单实现

  /**利用MD5进行加密
     * @param str  待加密的字符串
     * @return  加密后的字符串
     * @throws NoSuchAlgorithmException  没有这种产生消息摘要的算法
     * @throws UnsupportedEncodingException  
     */
    public String EncoderByMd5(String str) throws NoSuchAlgorithmException, UnsupportedEncodingException{
        //确定计算方法
        MessageDigest md5=MessageDigest.getInstance("MD5");
        BASE64Encoder base64en = new BASE64Encoder();
        //加密后的字符串
        String newstr=base64en.encode(md5.digest(str.getBytes("utf-8")));
        return newstr;
    }
2)进阶实现

public String MD5(String s){

                   try{

                            //将字符串转为byte数组

                            byte[]b=s.getBytes();

                            //获取MessageDigest对象,申明使用MD5算法进行加密(还有SHA算法)

                            MessageDigestmd=MessageDigest.getInstance("MD5");

                            //输入报文

                            md.update(b);

                            //生成摘要

                            byte[] bytes=md.digest();

                            //返回16进制字符串,用于储存在数据库中

                            returnbyte2str(bytes);

                   }catch(Exception exception){

                            exception.printStackTrace();

                            return null;

                   }

         }

        

         /* 把字节数组转为16进制字符串 */

         public String byte2str(byte[] b){

         char[]hexNumsStr={'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};

     intlen=b.length;

                   char[] result=newchar[len*2];

                   int k=0;

                   for(int i=0;i<len;i++){

                   //b[i]>>>4   不考虑符号(正负数)向右移4位

                   //b[i]&0xf       与0xf进行按位与

                   //0xf二进制为:1111

                            result[k++]=hexNumsStr[b[i]>>>4&0xf];

                            result[k++]=hexNumsStr[b[i]&0xf];

                   }

                   return new String(result);

   }

步骤及知识点整理
1)MessageDigest对象提供了信息摘要算法,如MD5算法或者SHA算法.在初始化MessageDigest的使用,要申明使用什么算法,如:MessageDigest   md5=MessageDigest.getInstance(“MD5”);
2)有了MessageDigest之后,通过update(byte[]input)方法,提供报文,因为该方法不支持String类型,但是支持byte[]类型(字节数组),所以把传入的String类型的参数转为byte[]类型(一般传入的为 密码  这个字段),如:byte[] b=s.getBytes();
3)传入报文之后,用digest()方法生成摘要,digest()返回的是byte[]类型。
PS: 1>digest()方法执行之前,update()可以执行多次,执行多次的效果等于把这多次的str.getBytes[]的str拼接成一个String类型的字符串,经过getBytes()之后使用update()
例如
2>digest()方法执行完之后,MessageDigest就被重新设定为初始状态,需要重新提供报文.

              MessageDigest md5 =MessageDigest.getInstance("MD5");//申明使用MD5算法

              md5.update("a".getBytes());//

              System.out.println("md5(a)="+byte2str(md5.digest()));

              md5.update("bc".getBytes());

              System.out.println("md5(bc)="+byte2str(md5.digest()));

               md5.update("a".getBytes());

              md5.update("bc".getBytes());

              System.out.println("md5(abc)="+byte2str(md5.digest()));
4)有了digest()方法的byte[]类型的结果之后,一般都要把字符数组转为16进制的字符串数组存入,然后再数据库

 

更多内容请关注微信公众号“外里科技

MD5算法原理及其实现_算法