md5加密算法~Java语言实现

前言

密码是现在生活中非常常见的东西,平时使用QQ需要密码,使用微信需要密码,玩游戏等等很多地方都需要用到密码。

但是很多人可能会对我们使用软件的时候输入的密码产生一定的误解,以为密码其实和账号没什么区别。只是名字不同。其实,在大多数情况下,用户输入的密码都是经过加密算法加密后才会存到数据库中。

如果不这么做的话,假如一个软件或者网站已经上线,并且拥有了一定数量的用户。后台程序员就可以随心所欲的获得用户的密码任意修改,这样一来安全性是很低的。而对于中小型项目,在众多的加密算法中,Md5还是用的比较多。

开发中常用的安全框架如shiro,spring security都内嵌了md5加密算法。包括 jdk 1.8 自带的 java.security也能使用md5加密。那么今天这里就手动实现一下~

Md5简介

Md5是一种被广泛使用的密码散列函数,可以产生出一个128位(16字节)的散列值(hash value),用于确保信息传输完整一致。MD5由美国密码学家罗纳德·李维斯特(Ronald Linn Rivest)设计,于1992年公开,用以取代MD4算法。这套算法的程序在 RFC 1321 标准中被加以规范。1996年后该算法被证实存在弱点,可以被加以破解,对于需要高度安全性的数据,专家一般建议改用其他算法,如SHA-2。2004年,证实MD5算法无法防止碰撞(collision),因此不适用于安全性认证,如SSL公开密钥认证或是数字签名等用途。

MD5由MD4、MD3、MD2改进而来,主要增强算法复杂度和不可逆性。MD5算法因其普遍、稳定、快速的特点,仍广泛应用于普通数据的加密保护领域

Md5加密算法的历史和介绍

Rivest在1989年开发出MD2算法。在这个算法中,首先对信息进行数据补位,使信息的字节长度是16的倍数。然后,以一个16位的校验和追加到信息末尾,并且根据这个新产生的信息计算出散列值。后来,Rogier和Chauvaud发现如果忽略了校验和MD2将产生冲突。MD2算法加密后结果是唯一的(即不同信息加密后的结果不同)

罗纳德·李维斯特(Ronald L. Rivest)

为了加强算法的安全性,Rivest在1990年又开发出MD4算法 。MD4算法同样需要填补信息以确保信息的比特位长度减去448后能被512整除(信息比特位长度mod 512 = 448)。然后,一个以64位二进制表示的信息的最初长度被添加进来。信息被处理成512位damgard/merkle迭代结构的区块,而且每个区块要通过三个不同步骤的处理。Den boer和Bosselaers以及其他人很快的发现了攻击MD4版本中第一步和第三步的漏洞。Dobbertin向大家演示了如何利用一部普通的个人电脑在几分钟内找到MD4完整版本中的冲突(这个冲突实际上是一种漏洞,它将导致对不同的内容进行加密却可能得到相同的加密后结果)

1991年,Rivest开发出技术上更为趋近成熟的MD5算法。它在MD4的基础上增加了"安全带"(safety-belts)的概念。虽然MD5比MD4复杂度大一些,但却更为安全。这个算法很明显的由四个和MD4设计有少许不同的步骤组成。在MD5算法中,信息-摘要的大小和填充的必要条件与MD4完全相同。Den boer和Bosselaers曾发现MD5算法中的假冲突(pseudo-collisions),但除此之外就没有其他被发现的加密后结果了

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) 字的整数倍

算法步骤

首先我们需要定义四个临时变量
   /**四个链接变量*/private static final int A=0x67452301;private static final int B=0xefcdab89;private static final int C=0x98badcfe;private static final int D=0x10325476;/**ABCD的临时变量*/private static int Atemp,Btemp,Ctemp,Dtemp;
公式:floor(abs(sin(i+1))×(2pow32)
 private static final int K[]={0xd76aa478,0xe8c7b756,0x242070db,0xc1bdceee,0xf57c0faf,0x4787c62a,0xa8304613,0xfd469501,0x698098d8,0x8b44f7af,0xffff5bb1,0x895cd7be,0x6b901122,0xfd987193,0xa679438e,0x49b40821,0xf61e2562,0xc040b340,0x265e5a51,0xe9b6c7aa,0xd62f105d,0x02441453,0xd8a1e681,0xe7d3fbc8,0x21e1cde6,0xc33707d6,0xf4d50d87,0x455a14ed,0xa9e3e905,0xfcefa3f8,0x676f02d9,0x8d2a4c8a,0xfffa3942,0x8771f681,0x6d9d6122,0xfde5380c,0xa4beea44,0x4bdecfa9,0xf6bb4b60,0xbebfbc70,0x289b7ec6,0xeaa127fa,0xd4ef3085,0x04881d05,0xd9d4d039,0xe6db99e5,0x1fa27cf8,0xc4ac5665,0xf4292244,0x432aff97,0xab9423a7,0xfc93a039,0x655b59c3,0x8f0ccc92,0xffeff47d,0x85845dd1,0x6fa87e4f,0xfe2ce6e0,0xa3014314,0x4e0811a1,0xf7537e82,0xbd3af235,0x2ad7d2bb,0xeb86d391};
向左位移数,计算方法未知
private static final int s[]={7,12,17,22,7,12,17,22,7,12,17,22,7,12,17,22,5,9,14,20,5,9,14,20,5,9,14,20,5,9,14,20,4,11,16,23,4,11,16,23,4,11,16,23,4,11,16,23,6,10,15,21,6,10,15,21,6,10,15,21,6,10,15,21};
初始化函数
private static void init(){Atemp=A;Btemp=B;Ctemp=C;Dtemp=D;}
移动一定的位数
  private  static  int  shift(int a,int s){return(a<<s)|(a>>>(32-s));//右移的时候,高位一定要补零,而不是补充符号位}
填充函数,处理后应满足bits≡448(mod512),字节就是bytes≡56(mode64),填充方式为先加一个0,其它位补零,最后加上64位的原来长度。
private static int[] add(String str){int num=((str.length()+8)/64)+1;//以512位,64个字节为一组int strByte[]=new int[num*16];//64/4=16,所以有16个整数for(int i=0;i<num*16;i++){//全部初始化0strByte[i]=0;}int    i;for(i=0;i<str.length();i++){strByte[i>>2]|=str.charAt(i)<<((i%4)*8);//一个整数存储四个字节,小端序}strByte[i>>2]|=0x80<<((i%4)*8);//尾部添加1/**添加原长度,长度指位的长度,所以要乘8,然后是小端序,所以放在倒数第二个,这里长度只用了32位*/strByte[num*16-2]=str.length()*8;return strByte;}
主循环
    private static void MainLoop(int M[]){int F,g;int a=Atemp;int b=Btemp;int c=Ctemp;int d=Dtemp;for(int i = 0; i < 64; i ++){if(i<16){F=(b&c)|((~b)&d);g=i;}else if(i<32){F=(d&b)|((~d)&c);g=(5*i+1)%16;}else if(i<48){F=b^c^d;g=(3*i+5)%16;}else{F=c^(b|(~d));g=(7*i)%16;}int tmp=d;d=c;c=b;b=b+shift(a+F+K[i]+M[g],s[i]);a=tmp;}Atemp=a+Atemp;Btemp=b+Btemp;Ctemp=c+Ctemp;Dtemp=d+Dtemp;}
整数变成16进制字符串
    private static String changeHex(int a){String str="";for(int i=0;i<4;i++){str+=String.format("%2s", Integer.toHexString(((a>>i*8)%(1<<8))&0xff)).replace(' ', '0');}return str;}
最后调用(注:上面的方法都是私有,唯独这个调用的公有)
   public static String getMD5(String source){init();int strByte[]=add(source);for(int i=0;i<strByte.length/16;i++){int num[]=new int[16];for(int j=0;j<16;j++){num[j]=strByte[i*16+j];}MainLoop(num);}return changeHex(Atemp)+changeHex(Btemp)+changeHex(Ctemp)+changeHex(Dtemp);}

md5加密算法~Java语言实现相关推荐

  1. php md5加密算法源码,MD5加密和哈希算法

    MD5加密算法为现在应用最广泛的哈希算法之一,该算法广泛应用于互联网网站的用户文件加密,能够将用户密码加密为128位的长整数.数据库并不明文存储用户密码,而是在用户登录时将输入密码字符串进行MD5加密 ...

  2. MD5加密算法及Java实现

    MD5加密算法及Java实现 上个学期在学数据库的时候,大作业是用Java Web+MySQL实现一个简易的系统,其中老师就提到了MD5算法,用来将用户提交的密码进行加密后放在数据库中,以防被泄露.在 ...

  3. md5加密算法原理及其GO语言实现

    md5加密算法原理及其GO语言实现 MD5讯息摘要演算法(英语:MD5 Message-Digest Algorithm),一种被广泛使用的密码杂凑函数,可以产生出一个128位元(16位元组)的散列值 ...

  4. MD5单向,加密算法-java

    md5算法是一种常见的单项加密算法,例如mysql中的MD5()函数: 今天记录一下关于Java模块的md5加密算法应用 与编写: md可以用到hibernate; 模块位于java.security ...

  5. MD5加密算法及其在Java中的使用

    MD5算法简介 MD5是不可逆的单向加密算法,因为哈希算法是不可逆的,简单来说,就像我们可以获知5%2=1,3%2=1,7%2=1,但是,当我们仅仅拿到结果1的时候并不知道这是哪个数对2取余得到的结果 ...

  6. java md5加密长度_java中使用MD5加密算法进行加密

    java中使用MD5加密算法进行加密以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! 在各种应用系统的开发中 经常需要存储 ...

  7. C语言实现MD5加密算法

    转载声明:http://blog.csdn.net/haroroda/article/details/45935099 这次我分享的是MD5加密算法.其实MD5这个大名在还没上密码学课之前我就听说过了 ...

  8. java自带的md5加密_JDK自带MD5加密算法

    [     在各种应用系统的开发中,经常需要存储用户信息,很多地方都要存储用户密码,而将用户密码直接存储在服务器上显然是不安全的,本文简要介绍工作中常用的 MD5加密算 其实jdk就自带了md5加密算 ...

  9. Java中md5加密算法

    md5加密 在实际开发中对用户的信息需要加密,比如密码,我们会使用加密算法进行加密,最常用的就是md5加密算法 应用场景,用户的注册,用户登录,修改密码时进行加密解密操作 md5加密逻辑:我们可以认为 ...

  10. 简要分析用MD5加密算法加密信息(如有疑问,敬请留言)

    一.引言 最近看了媒体的一篇关于"网络上公开叫卖个人隐私信息"报导,不法分子通过非法手段获得的个人隐私信息,其详细.准确程度简直令人瞠口结舌.在互联网飞速发展的现在,我们不难想到, ...

最新文章

  1. 使用文件给swap增加空间
  2. DAG情况下如何移动数据库路径
  3. shell脚本中使用seq生成连续整数
  4. linux的~和/的区别
  5. 【最全最详细】使用publiccms实现动态可维护的导航菜单栏
  6. 微软MIX11大会第一天主旨以及新产品发布总结
  7. Learning中的代数结构的建立
  8. Fig. BPF Performance Tools Book
  9. mysql学习之路三(转)
  10. 如何在SQL Server中使用级联删除?
  11. Linux基础-1.Linux命令及获取帮助
  12. rap格式鸿蒙,你,想要成为rap star吗?
  13. 美容院前台收银软件用什么好?
  14. 太虚幻境 文/江湖一劍客
  15. 15支持哪些数据库版本 tfs_版本和支持的功能 - SQL Server 2016 | Microsoft Docs
  16. 微服务项目部署服务器,第3章 3.2 部署服务器 - 编排多个微服务
  17. VScode 搜索全局文件
  18. vue入门(一)----工程vue_sell
  19. ffserver服务器实现WebM格式视频直播
  20. 基于MATLAB 2021b的机器学习、深度学习

热门文章

  1. web前端基础知识 - CSS语言和功能
  2. 浅谈融云即时通讯服务「日志优化」
  3. 第十届飞思卡尔杯智能车竞赛规则解读
  4. Adbyby无法更新规则的解决方案
  5. Linux的mysql主从配置
  6. android体脂代码,该减肥了吗?教你用手机App测量体脂率
  7. 服务器组态文件己写保护,组态王常见问题集锦(一)
  8. 如何下载网页中的视频文件?
  9. 3D图形学(4):纹理贴图
  10. 前端对页面中的 checked 选中状态的展示