首页 > 代码库 > MD5的学习与练习

MD5的学习与练习

MD5加密的Java实现

    在各种应用系统中,如果需要设置账户,那么就会涉及到存储用户账户信息的问题,为了保证所存储账户信息的安全,通常会采用MD5加密的方式来,进行存储。首先,简单得介绍一下,什么是MD5加密。
        MD5的全称是Message-Digest Algorithm 5 (信息-摘要算法),在90年代初,由MIT Laboratory for Computer Scientce 和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中有详细的描述,这是一份最权威的文档,由Ronald L.Rivest在1992年8月向IETF提交。

        (一)消息摘要简介
            一个消息摘要就是一个数据块的数字指纹。即对一个任意长度的一个数据块进行计算,产生一个唯一指印(对于SHA1是产生一个20字节的二进制数组)。消息摘要是一种与消息认证码结合使用以确保消息完整性的技术。主要使用单向散列函数算法,可用于检验消息的完整性,和通过散列密码直接以文本形式保存等,目前广泛使用的算法由MD4、MD5、SHA-1.

        消息摘要有两个基本属性:
            1.两个不同的报文难以生成相同的摘要
            2.难以对指定的摘要生成一个报文,而可以由改报文反推算出该指定的摘要
        代表:美国国家标准技术研究所的SHA1和麻省理工学院Ronald Rivest提出的MD5

        (二)对字符串进行加密

package test;import java.io.UnsupportedEncodingException;import java.security.MessageDigest;import java.security.NoSuchAlgorithmException;import sun.misc.BASE64Encoder;/** * 对字符串进行加密 * @param str  待加密的字符串 * @return  加密后的字符串 * @throws NoSuchAlgorithmException  没有这种产生消息摘要的算法 * @throws UnsupportedEncodingException  */public class Demo01 {        public static 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;    }        public static void main(String[] args) throws NoSuchAlgorithmException, UnsupportedEncodingException {        String str = "0123456789";        System.out.println(EncoderByMd5(str));    }}

 


        (三)验证密码是否正确

package test;import java.io.UnsupportedEncodingException;import java.security.NoSuchAlgorithmException;/** * 判断用户密码是否正确 * @param newpasswd  用户输入的密码 * @param oldpasswd  数据库中存储的密码--用户密码的摘要 * @return * @throws NoSuchAlgorithmException * @throws UnsupportedEncodingException * */public class Demo02 {    public static boolean checkpassword(String newpasswd, String oldpasswd) throws NoSuchAlgorithmException, UnsupportedEncodingException{        if (Demo01.EncoderByMd5(newpasswd).equals(oldpasswd)) {            return true;        } else {            return false;        }    }        public static void main(String[] args) throws NoSuchAlgorithmException, UnsupportedEncodingException {        System.out.println("old:"+Demo01.EncoderByMd5("123"));        System.out.println("new:"+Demo01.EncoderByMd5("123"));        System.out.println(checkpassword("123",Demo01.EncoderByMd5("123")));    }}

 


            因为MD5是基于消息摘要原理的,消息摘要的基本特征就是很难根据摘要推算出消息报文,因此要验证密码是否正确,就必须对输入密码(消息报文)重新计算其摘要,和数据库中存储的摘要进行对比(即数据库中存储的其实为用户密码的摘要),若两个摘要相同,则说明密码正确,不同,则说明密码错误。

 

练习:

技术分享
package test;import java.security.MessageDigest;import java.security.NoSuchAlgorithmException;/** * Java实现MD5加密算法(使用MessageDigest) * MD5加密算法,即"Message-Digest Algorithm 5 (信息-摘要算法)",它由MD2、MD3、 * MD4发展而来的一种单向函数算法(也就是HASH算法),它是国际著名的公钥加密算法标准RSA的第一设计者 * R.Rivest于上个世纪90年代初开发而来的。MD5的最大作用在于,将不同格式的大容量文件信息在用数字签名 * 软件来签署私人秘钥前"压缩"成一种保密格式,关键之处在于--这种"压缩"是不可逆的。Java JDK已经自带 * 了MD5的实现,只要简单调用下就可以。 *  * @author Administrator * */public class CreateMD5 {    //静态方法,便于工具类    public  static String getMd5(String plainText){        try {            MessageDigest md = MessageDigest.getInstance("MD5");            md.update(plainText.getBytes());            byte b[] = md.digest();                        int i;                        StringBuffer buf = new StringBuffer("");            for (int offset = 0; offset < b.length; offset++) {                i = b[offset];                if (i < 0)                     i += 256;                if (i < 16)                     buf.append("0");                buf.append(Integer.toHexString(i));            }            //32位加密            return buf.toString();            // 16位的加密            // return buf.toString().substring(8,24);        } catch (NoSuchAlgorithmException e) {            e.printStackTrace();            return null;        }    }        public static void main(String[] args) {        //测试        System.out.println(CreateMD5.getMd5("hello"));    }}
Java实现MD5加密算法
技术分享
package test;import java.security.MessageDigest;import java.security.NoSuchAlgorithmException;/** * 使用java获取md5值的两种方法 * 1.Message Digest Algorithm MD5 (中文名为消息摘要算法第五版) * 为计算机安全领域广泛使用的一种散列函数,是一种比较常用的哈希算法。 * 2.导入包:commons-codec * @author Administrator * */public class md5_test {    //MD5的字符串常量    private final static String[] hexDigits = {"0","1","2","3","4","5","6","7","8","9","a","b","c","d","e","f"};    public static void main(String[] args) {        try {            MessageDigest messageDigest = MessageDigest.getInstance("MD5");            System.out.println(byteArrayToHexString(messageDigest.digest("baidu.com".getBytes())));        } catch (NoSuchAlgorithmException e) {            e.printStackTrace();        }    }    private static String byteArrayToHexString(byte[] b) {        StringBuffer resultSb = new StringBuffer();        for (int i = 0; i < b.length; i++) {            resultSb.append(byteToHexString(b[i]));        }        return resultSb.toString();    }    /**     * 将一个字节转化成十六进制形式的字符串     *      * @param b     * @return     */    private static String byteToHexString(byte b) {        int n = b;        if (n < 0)            n = 256 + n;            int d1 = n / 16;            int d2 = n % 16;            return hexDigits[d1]+hexDigits[d2];    }}
使用java获取md5值的两种方法
技术分享
package test;import java.math.BigInteger;import java.security.MessageDigest;import java.security.NoSuchAlgorithmException;/** * MD5加密 * @author Administrator * */public class MD5 {    public static void main(String[] args) {        System.out.println(MD5.getMD5("123456"));    }    /**     * 用md5 编码后的码值     *      * @param sInput     * 明码     * @return md5加密后的密码     */    private static String getMD5(String sInput) {                String algorithm ="";        if (sInput == null) {            return "null";        }                try {            algorithm = System.getProperty("MD5.algorithm","MD5");        } catch (SecurityException se) {        }        MessageDigest md = null;        try {            md = MessageDigest.getInstance(algorithm);        } catch (NoSuchAlgorithmException e) {            e.printStackTrace();        }        byte buffer[] = sInput.getBytes();                for (int count = 0; count < sInput.length(); count++) {            md.update(buffer,0,count);        }        byte bDigest[] = md.digest();        BigInteger bi = new BigInteger(bDigest);        return (bi.toString(16));    }}
MD5加密
技术分享
package test;import java.io.File;import java.io.FileInputStream;import java.io.IOException;import java.io.InputStream;import java.security.MessageDigest;import java.security.NoSuchAlgorithmException;import java.security.Provider;import java.security.Security;import java.util.HashSet;import java.util.Iterator;import java.util.Set;import org.apache.commons.codec.digest.DigestUtils;import sun.applet.Main;import sun.awt.image.BytePackedRaster;/** * java计算过G文件md5 值计算 *  * @author Administrator * */public class Md5CaculateUtil {        private Md5CaculateUtil(){            }        private static char[] hexChar = {        ‘0‘,‘1‘,‘2‘,‘3‘,‘4‘,‘5‘,‘6‘,‘7‘,‘8‘,‘9‘,        ‘a‘,‘b‘,‘c‘,‘d‘,‘e‘,‘f‘    };        public static String getHash(String fileName,String hashType)    throws IOException, NoSuchAlgorithmException{                File f = new File(fileName);        System.out.println("---------------------------------");        System.out.println("|当前文件名称:"+f.getName());        System.out.println("|当前文件大小:"+f.length()/1024/1024+"MB");        System.out.println("|当前文件路径[绝对]:"+f.getAbsolutePath());        System.out.println("|当前文件路径[---]:"+f.getCanonicalPath());        System.out.println("---------------------------------");                InputStream ins = new FileInputStream(f);                byte[] buffer = new byte[8192];        MessageDigest md5 = MessageDigest.getInstance(hashType);                int len;        while ((len = ins.read(buffer)) != -1) {            md5.update(buffer, 0, len);        }                ins.close();        // 也可以用apache自带的计算MD5方法        return DigestUtils.md5Hex(md5.digest());        // 自己写的转计算MD5方法        // return toHexString(md5.digest());    }        public static String getHash2(String fileName){        File f = new File(fileName);        return String.valueOf(f.lastModified());    }        protected static String toHexString(byte[] b){        StringBuilder sb = new StringBuilder(b.length*2);        for (int i = 0; i < b.length; i++) {            sb.append(hexChar[(b[i] & 0xf0) >>> 4]);            sb.append(hexChar[b[i] & 0x0f]);        }        return sb.toString();    }        /**     * 获取MessageDigest支持几种加密算法     */    @SuppressWarnings({"rawtypes","unchecked"})    private static String[] getCryptolmpls(String serviceType){                Set result = new HashSet();        // all prividers        Provider[] providers = Security.getProviders();        for (int i = 0; i < providers.length; i++) {            // get services provided by each provider            Set keys = providers[i].keySet();            for (Iterator it = keys.iterator(); it.hasNext();) {                String key = it.next().toString();                key = key.split(" ")[0];                                if (key.startsWith(serviceType+".")) {                    result.add(key.substring(serviceType.length()+1));                } else if (key.startsWith("Alg.Alias."+serviceType+".")) {                        result.add(key.substring(serviceType.length(), 11));                    }                }            }        return (String[]) result.toArray(new String[result.size()]);    }        public static void main(String[] args) throws NoSuchAlgorithmException, IOException {        // 调用方法        // String[] names = getCryptolmpls("MessageDigest");        // for(String name : names){        //   System.out.println(name);    //        }        long start = System.currentTimeMillis();        System.out.println("开始计算文件MD5值,请稍后...");        String fileName = "E:\\Office_2010_Tookit_2.2.3XiaZaiBa.zip";        // String fileName = "E:\\SoTowerStudio-3.1.0.exe";        String hashType = "MD5";        String hash = getHash(fileName, hashType);        System.out.println("MD5"+hash);        long end = System.currentTimeMillis();        System.out.println("一共耗时:"+(end-start)+"毫秒");    }}
java计算过G文件md5 值计算
技术分享
package test;import java.math.BigInteger;import java.security.MessageDigest;import java.security.NoSuchAlgorithmException;import exception.SpeedException;/** * Java三行代码搞定MD5加密 *  * 对字符串md5加密 *  * @param str * @return * */public class MD5Demo {    public static String getMD5(String str) throws SpeedException{        try {            // 生成一个MD5加密计算摘要            MessageDigest md = MessageDigest.getInstance("MD5");            // 计算md5函数            md.update(str.getBytes());            // digest()最后确定返回md5 hash值,返回值为字符串。因为md5 hash值是16位的hex值,实际上就是8位的字符            // BigInteger函数则将8位的字符串转换成16位hex值,用字符串来表示,得到字符串形式的hash值            return new BigInteger(1,md.digest()).toString(16);        } catch (Exception e) {            throw new SpeedException("MD5加密出现错误");        }    }        public static void main(String[] args) throws SpeedException {        System.out.println(getMD5("123"));;    }}
Java三行代码搞定MD5加密
技术分享
package test;import java.security.MessageDigest;/** * 利用Java自带的MD5加密 *  * @author Administrator * */public class MD5Util {    public final static String MD5(String s){        char hexDigits[]={‘0‘,‘1‘,‘2‘,‘3‘,‘4‘,‘5‘,‘6‘,‘7‘,‘8‘,‘9‘,‘A‘,‘B‘,‘C‘,‘D‘,‘E‘,‘F‘};            try {            byte[] btInput = s.getBytes();            //获得MD5摘要算法的 MessageDigest 对象            MessageDigest mdInst = MessageDigest.getInstance("MD5");            //使用指定的字节更新摘要            mdInst.update(btInput);            //获得密文            byte[] md = mdInst.digest();            //把密文转换成十六进制的字符串形式            int j = md.length;            char str[] = new char[j * 2];            int k = 0;            for (int i = 0; i < j; i++) {                byte byte0 = md[i];                str[k++] = hexDigits[byte0 >>> 4 & 0xf];                str[k++] = hexDigits[byte0 & 0xf];            }            return new String(str);        } catch (Exception e) {            e.printStackTrace();            return null;        }        }    public static void main(String[] args) {        System.out.println(MD5Util.MD5("20121221"));        System.out.println("加密");    }}
利用Java自带的MD5加密
技术分享
package test;import java.io.File;import java.io.FileInputStream;import java.io.FileNotFoundException;import java.io.IOException;import java.math.BigInteger;import java.nio.MappedByteBuffer;import java.nio.channels.FileChannel;import java.security.MessageDigest;import org.apache.commons.codec.digest.DigestUtils;import org.apache.commons.io.IOUtils;/** * Java读取文件MD5的两种方案 * 1.MessageDigest实现 * 2.org.apache.commons.codec.digest实现 *  * @author Administrator * */public class testMD5 {        public static String getMd5ByFile(File file) throws FileNotFoundException{        String value = null;        FileInputStream in = new FileInputStream(file);                try {            MappedByteBuffer byteBuffer = in.getChannel().map(FileChannel.MapMode.READ_ONLY, 0, file.length());            MessageDigest md5 = MessageDigest.getInstance("MD5");            md5.update(byteBuffer);            BigInteger bi = new BigInteger(1,md5.digest());            value = bi.toString(16);        } catch (Exception e) {            e.printStackTrace();        } finally {            if (null != in) {                try {                    in.close();                } catch (IOException e) {                    e.printStackTrace();                }            }        }        return value;    }        public static void main(String[] args) throws IOException {                String path ="E:\\commons-codec-1.10-bin.zip";                String v = getMd5ByFile(new File(path));        System.out.println("MD5:"+v.toUpperCase());                FileInputStream fis = new FileInputStream(path);        String md5 = DigestUtils.md5Hex(IOUtils.toByteArray(fis));        IOUtils.closeQuietly(fis);        System.out.println("MD5:"+md5);        //        System.out.println("MD5"+DigestUtils.md5Hex("WANGQIUYUN"));    }}
Java读取文件MD5的两种方案
技术分享
package test;import org.apache.commons.codec.digest.DigestUtils;public class ToMain {    public static void main(String[] args) {        System.out.println(DigestUtils.md5Hex("baidu.com"));    }}
ToMain
技术分享
package exception;public class SpeedException extends Exception {    public SpeedException(String msg)      {          super(msg);      }  }
SpeedException

 

MD5的学习与练习