一、MD5是什么?

基本知识:

MD5的固定长度为128位也就是16字节,通常我们用他的16进制字面值来输出它

MD5的特点:

1.长度固定,无论输入多少字节输出总是16字节

2.不可逆,就是从结果无法反推原始数据,因为不管输入多大的数据输出总是十六字节中间一定被丢掉了一些信息。

3.具有高度离散性,就是输出的16进制数据没有任何规律可言,哪怕输入改变了一个比特输出的结果也完全不同,也可以说MD5的输出结果无法预测。

4.抗碰撞性,意思是想找到两个不同的数据产生的MD5一致是非常困难的也可以说在原始数据固定的情况下先找到另一段数据跟这份数据生成相同的MD5是几乎不可能完成的任务。

综上所属MD5常用于一下几种场景

1.用户密码保护,在保存密码时不记录密码本身,只记录密码是 MD5结果。只有用户自己知道密码铭文,校验时只要密码正确得到的MD5一定是一样的。好处是即便密码数据库被盗也无法通过MD5反推出来铭文是什么,使得密码保存更安全。

2.文件完整性校验,比如我们要传输一个非常大的文件由于网络中的不可靠因素有可能导致文件传输不完整或被串改。如何校验接收端文件与发送端一致呢?只需要现在发送端计算一边MD5并把这个结果发送给接收端。接受端在文件传输完成后也计算一次MD5,如果这两次结果一致,那文件一定是完整的。

3.数字签名,发布一个程序为了防止程序被植入木马,我可以在发布程序时同事发布其MD5这样别人下载程序后,只需要自己计算一遍MD5是否与我发布的相同就知道程序有没有被人篡改。根据MD5的不可逆性与抗碰撞性,篡改者几乎不可能使篡改后的程序MD5与原来的MD5相同

4.云盘秒传,我们在使用云盘有时上传一个很大的文件几乎秒传,它并不是真的把文件上传了,它只需要计算一下啊文件的MD5,并且在自己的数据库中搜索一下这个MD5是否存在。如果存在那就不用上传了直接使用已存在的文件就可以了从而实现文件妙传

二、MD5的操作:

1.补位:对输入的内容进行补位,补位是对长度进行补齐的操作使得长度变成N*512+448

2.标准幻术:4*4=16字节

三、MD5的具体操作方式

MD5加密密码

public static String md5(String content) {
        byte[] hash;
        try {
            hash = MessageDigest.getInstance("MD5").digest(content.getBytes("UTF-8"));
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException("NoSuchAlgorithmException",e);
        } catch (UnsupportedEncodingException e) {
            throw new RuntimeException("UnsupportedEncodingException", e);
        }

        StringBuilder hex = new StringBuilder(hash.length * 2);
        for (byte b : hash) {
            if ((b & 0xFF) < 0x10){
                hex.append("0");
            }
            hex.append(Integer.toHexString(b & 0xFF));
        }
        return hex.toString();
    }

运用MD5加密文件

public static String md5ForFile(File file){
        int buffersize = 1024;
        FileInputStream fis = null;
        DigestInputStream dis = null;

        try {
            //创建MD5转换器和文件流
            MessageDigest messageDigest =MessageDigest.getInstance("MD5");
            fis = new FileInputStream(file);
            dis = new DigestInputStream(fis,messageDigest);

            byte[] buffer = new byte[buffersize];
            //DigestInputStream实际上在流处理文件时就在内部就进行了一定的处理
            while (dis.read(buffer) > 0);

            //通过DigestInputStream对象得到一个最终的MessageDigest对象。
            messageDigest = dis.getMessageDigest();

            // 通过messageDigest拿到结果,也是字节数组,包含16个元素
            byte[] array = messageDigest.digest();
            // 同样,把字节数组转换成字符串
            StringBuilder hex = new StringBuilder(array.length * 2);
            for (byte b : array) {
                if ((b & 0xFF) < 0x10){
                    hex.append("0");
                }
                hex.append(Integer.toHexString(b & 0xFF));
            }
            return hex.toString();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

        return null;
    }

总结:工作中遇到加密问题,刚开始用MD5加密后来又换成了rsa加密,下一篇介绍rsa,希望可以帮到你。

Logo

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。

更多推荐