MD5 加密算法介绍以及使用

来源:互联网 发布:重庆软件行业协会地址 编辑:程序博客网 时间:2024/05/17 13:46

MD5 算法的介绍

特点
1、压缩性:任意长度的数据,算出的MD5值长度都是固定的。
2、容易计算:从原数据计算出MD5值很容易。
3、抗修改性:对原数据进行任何改动,哪怕只修改1个字节,所得到的MD5值都有很大区别。
4、强抗碰撞:已知原数据和其MD5值,想找到一个具有相同MD5值的数据(即伪造数据)是非常困难的。

用途

1.可以用于加密用户密码
2.可以用于应用安装包的一致性验证

MD5 的简单使用

public class MessageDigestUtil {    public static String encryptMD5(byte[] data)            throws NoSuchAlgorithmException {        MessageDigest md5 = MessageDigest.getInstance("MD5");        md5.update(data);// data 是要加密的信息,格式为 byte 数组        byte[] resultBytes = md5.digest();//即是经过 MD5 加密过后生成的 byte 数组        String resultString = resultBytes.toString();        return resultString;    }}

写完之后我们想验证一下数据经过 MD5 加密后回生成怎样的信息,写个主函数类似如下

public class Main {    public static final String DATA = "hwaphon";    /**     * @param args     * @throws Exception     */    public static void main(String[] args) throws Exception {        String result = MessageDigestUtil.encryptMD5(DATA.getBytes());        System.out.println(result);    }}

运行程序,输出如下

[B@15db9742

这个时候我们发现这好像不是我们平常见到的 MD5 格式,对的,我们平常所见的都是 16进制的,而现在是 byte 形式,所以我们需要将其转换为 十六进制,怎么转换呢?

public class Helper {    public static String bytesToHexString(byte[] src) {        StringBuilder stringBuilder = new StringBuilder("");        if (src == null || src.length <= 0) {            return null;        }        for (int i = 0; i < src.length; i++) {            int v = src[i] & 0xFF;            String hv = Integer.toHexString(v);            if (hv.length() < 2) {                stringBuilder.append(0);            }            stringBuilder.append(hv);        }        return stringBuilder.toString();    }}

为什么这么转换呢?大家都知道,16进制每个字符需要 4位 2进制来表示,而 byte 用二进制则占8位,所以我们只需要将每个 byte 转化位两个 16进制表示即可。你可能还对int v = src[i] & 0xFF; 这一行有疑问,点击此处查看

经过上述转化后,将 String resultString = resultBytes.toString(); 转化为 String resultString = Helper.bytesToHexString(resultBytes);

再次运行程序,输出结果为 0dcd7314898e812f223ad0c61bc8a903 , 恩,貌似是那么回事了。

转化成这样又有什么用啊?首先我们想到,当我们写客户端程序时,用户登陆总不能用明文表示吧?如果真是这样的话,那么只要登录的时候数据流被截获,那么我们客户的数据信息可谓是一丝不挂。所以为了安全考虑,我们可以在对用户名和密码都进行MD5加密,注意 MD5 算法是不可逆的,也就是说就算MD5加密过后的数据被截获了,也不可能还原原数据。

验证一致性

当我们下载程序安装包的过程中,程序可能会被非法篡改,怎么判断自己下载的程序由没有被篡改呢? 有些程序在下载的时候,官方就会给出 MD5 的值,那么我们下载过后怎么用来验证呢?下面拿搜狗拼音安装包来举例,获取它的MD5值

public static String getMD5OfFile(String path) throws Exception {        FileInputStream stream = new FileInputStream(new File(path));        DigestInputStream digestInputStream = new DigestInputStream(stream,                MessageDigest.getInstance("MD5"));        byte[] buffer = new byte[1024];        int read = digestInputStream.read(buffer, 0, 1024);        while (read != -1) {            read = digestInputStream.read(buffer, 0, 1024);        }        MessageDigest dis = digestInputStream.getMessageDigest();        byte[] resultBytes = dis.digest();        String resultString = Helper.bytesToHexString(resultBytes);        return resultString;    }

测试一下

public class Main {    public static final String PATH = "sogoupinyin_2.0.0.0078_amd64.deb";    /**     * @param args     * @throws Exception     */    public static void main(String[] args) throws Exception {        String result = MessageDigestUtil.getMD5OfFile(PATH);        System.out.println(result);    }}

输出结果

0a4e81d7a9cae7e8597371b1fa3674aa

这个时候,如果我在下载的时候官方也提供给一个 MD5值,那么我现在就可以去比对了,如果完全吻合,说明我下载的程序没有被非法篡改,如果不一样,那么说明。。。。

3 0