• 每天找回一点点之MD5加密算法


    之前在做项目的时候用户密码都进行了MD5的加密,今天突然想起来了总结一下(●'◡'●)

    一.MD5是什么?

          MD5信息摘要算法(英语:MD5 Message-Digest Algorithm),一种被广泛使用的密码散列函数,可以产生出一个128位(16字节)的散列值(hash value),用于确保信息传输完整一致。MD5由美国密码学家罗纳德·李维斯特(Ronald Linn Rivest)设计,于1992年公开,用以取代MD4算法。这套算法的程序在 RFC 1321 标准中被加以规范。

      MD5是哈希散列算法,输入两个不同的明文不会得到相同的输出值,根据输出值,不能得到原始的明文,即其过程不可逆;所以要解密MD5没有现成的算法,只能用穷举法,把可能出现的明文,用MD5算法散列之后,把得到的散列值和原始的数据形成一个一对一的映射表,通过比在表中比破解密码的MD5算法散列值,通过匹配从映射表中找出破解密码所对应的原始明文。

    二.MD5属于加密算法吗?

      认为不属于的人是因为他们觉得不能从密文(散列值)反过来得到原文,即没有解密算法,所以这部分人认为MD5只能属于算法,不能称为加密算法;

      认为属于的人是因为他们觉得经过MD5处理后看不到原文,即已经将原文加密,所以认为MD5属于加密算法;

    三.MD5是否可逆?

      MD5不可逆的原因是其是一种散列函数,使用的是hash算法,在计算过程中原文的部分信息是丢失了的。

      不过有个地方值得指出的是,一个MD5理论上的确是可能对应无数多个原文的,因为MD5是有限多个的而原文可以是无数多个。比如主流使用的MD5将任意长度的“字节串映射为一个128bit的大整数。

    四.MD5如何实现?

      原理可简要的叙述为:MD5码以512位分组来处理输入的信息,且每一分组又被划分为16个32位子分组,经过了一系列的处理后,算法的输出由四个32位分组组成,将这四个32位分组级联后将生成一个128位散列值。

      按位补充数据

      在MD5算法中,首先需要对信息进行填充,这个数据按位(bit)补充,要求最终的位数对512求模的结果为448。也就是说数据补位后,其位数长度只差64位(bit)就是512的整数倍。即便是这个数据的位数对512求模的结果正好是448也必须进行补位。补位的实现过程:首先在数据后补一个1 bit; 接着在后面补上一堆0 bit, 直到整个数据的位数对512求模的结果正好为448。总之,至少补1位,而最多可能补512位。
     
    扩展长度
      在完成补位工作后,又将一个表示数据原始长度的64 bit数(这是对原始数据没有补位前长度的描述,用二进制来表示)补在最后。当完成补位及补充数据的描述后,得到的结果数据长度正好是512的整数倍。也就是说长度正好是16个(32bit) 字的整数倍。
     
    初始化MD缓存器
      MD5运算要用到一个128位的MD5缓存器,用来保存中间变量和最终结果。该缓存器又可看成是4个32位的寄存器A、B、C、D,初始化为
      A : 01 23 45 67
      B: 89 ab cd ef
      C: fe dc ba 98
      D: 76 54 32 10
     
    处理数据段
      首先定义4个非线性函数F、G、H、I,对输入的报文运算以512位数据段为单位进行处理。对每个数据段都要进行4轮的逻辑处理,在4轮中分别使用4个不同的函数F、G、H、I。每一轮以ABCD和当前的512位的块为输入,处理后送入ABCD(128位) 。
     
    输出
    信息摘要最终处理成以A, B, C, D 的形式输出。也就是开始于A的低位在前的顺序字节,结束于D的高位在前的顺序字节 。
     
    五.应用场景
      用于密码管理,电子签名,邮件垃圾筛选
    六.一个小小的JAVA测试(只是一个小模拟)
      
    package com.syq.test;
    
    import java.math.BigInteger;
    import java.security.MessageDigest;
    import java.security.NoSuchAlgorithmException;
    import java.util.Scanner;
    
    /**
     * 
     * @author KIRA
     * 第一次用户输入的数据用MD5算法计算后存入数据库
     * 用户再次输入密码之后再用MD5计算之后比较和数据库中的内容对比,一样的话密码就正确
     *
     */
    public class md5 {
        
        public static void main(String[] args) {
            String str;
            Scanner sc =new Scanner(System.in);
            System.out.print("please input password(first):");
            str=sc.next();
            try {
                MessageDigest md = MessageDigest.getInstance("md5");
                // 计算md5函数
                md.update(str.getBytes());
                
                // digest()最后确定返回md5 hash值,返回值为8为字符串。因为md5 hash值是16位的hex值,实际上就是8位的字符
                 // BigInteger函数则将8位的字符串转换成16位hex值,用字符串来表示;得到字符串形式的hash值
                String password= new BigInteger(1, md.digest()).toString(16);
                
                System.out.print("please input password(first):");
                String str1 = sc.next();
                md.update(str1.getBytes());
                String input = new BigInteger(1,md.digest()).toString(16);
                
                System.out.println(password);
                System.out.println(input);
                
                if(password.equals(input)){
                    System.out.print("welcome!");
                }else{
                    System.out.println("password is wrong!");
                }
            } catch (NoSuchAlgorithmException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            
        }
    
    }
    唯有热爱方能抵御岁月漫长。
  • 相关阅读:
    第45周星期六迟到的总结
    php实现第三方登录
    laravel5.4 前后台未登陆,跳转到各自的页面
    Laravel5.1 实现第三方登录认证教程之 微信登录
    php第三方登录(微博登录,仿照慕课网)
    微博第三方登录时,域名使用错误报错, Laravel \ Socialite \ Two \ InvalidStateException No message...
    艾伟_转载:如何开发绚丽、高效率的界面(Windows嵌入式系统) 狼人:
    艾伟_转载:扩展方法 之 Asp.Net篇 狼人:
    艾伟_转载:把委托说透(4):委托与设计模式 狼人:
    艾伟_转载:扩展方法 之 Redirect 篇 狼人:
  • 原文地址:https://www.cnblogs.com/syq816/p/12397732.html
Copyright © 2020-2023  润新知