巨人大哥谈Java面试中常考的信息安全方面知识(MD5)

Posted jurendage

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了巨人大哥谈Java面试中常考的信息安全方面知识(MD5)相关的知识,希望对你有一定的参考价值。

巨人大哥谈Java面试中常考的信息安全方面知识(MD5)

 

Java MD5 加密算法介绍以及使用

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);
    }

}

运行程序,输出如下

[[email protected]

这个时候我们发现这好像不是我们平常见到的 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值,那么我现在就可以去比对了,如果完全吻合,说明我下载的程序没有被非法篡改,如果不一样,那么说明。。。。

 







以上是关于巨人大哥谈Java面试中常考的信息安全方面知识(MD5)的主要内容,如果未能解决你的问题,请参考以下文章

Java面试题中常考的容易混淆的知识点区别

巨人大哥谈Java工程师高手之路

巨人大哥谈电商平台框架之后台管理框架

巨人大哥谈Web应用中的Session(session详解)

巨人大哥谈缓存在高并发场景下使用法则

巨人大哥谈《觉得做人累了就看看这些!不是社会错了,是你错了!》