转自:http://blog.csdn.net/nzfxx/article/details/51804193

大家好,我们现在来讲解关于加密方面的知识,说到加密我认为不得不提MD5,因为这是一种特殊的加密方式,它到底特殊在哪,现在我们就开始学习它

全称:message-digest algorithm 5 
翻译过来就是:信息 摘要 算法 5

1.特点

  • 1.长度固定:

    不管多长的字符串,加密后长度都是一样长 
    作用:方便平时信息的统计和管理

  • 2.易计算:

    字符串和文件加密的过程是容易的. 
    作用: 开发者很容易理解和做出加密工具

  • 3.细微性

    一个文件,不管多大,小到几k,大到几G,你只要改变里面某个字符,那么都会导致MD5值改变. 
    作用:很多软件和应用在网站提供下载资源,其中包含了对文件的MD5码,用户下载后只需要用工具测一下下载好的文件,通过对比就知道该文件是否有过更改变动.

  • 4.不可逆性

    你明明知道密文和加密方式,你却无法反向计算出原密码. 
    作用:基于这个特点,很多安全的加密方式都是用到.大大提高了数据的安全性


2.后续讲解

  • 关于撞库破解:

    这是概率极低的破解方法,原理就是:

    1.建立一个大型的数据库,把日常的各个语句,通过MD5加密成为密文,不断的积累大量的句子,放在一个庞大的数据库里.

    2.比如一个人拿到了别人的密文,想去查询真实的密码,就需要那这个密文去到提供这个数据库的公司网站去查询.

    这就是撞库的概念.


3.关于MD5加盐:

比如我的银行密码是”12345”

1.得到的MD5是:827ccb0eea8a706c4c34a16891f84e7b

2.一个人截取到这个密文,那么通过撞库肯定容易撞出12345.

3.我们要做的就是加盐,银行密码还是”12345”,然后我把银行密码加上我特定的字符串才计算MD5 
所以密码还是那个密码,但是变成求”12345密码加密987”的MD5值,然后再得到MD5,那么这个MD5起码可以确认那个数据库不会有.


说了那么多我们开始我们的MD5工具的制作

我们一般加密都是加密字符串或者文件,所以我们的工具就有加密字符串和文件的两种方法,两个方法同名,通过重载完成

1.加密字符串

逻辑思维:

  • 1.获取信息摘要对象:md5

    通过信息摘要单例的构造函数获取:

    MessageDigest md5 = MessageDigest.getInstance("MD5");
    • 1
    • 2
  • 2.信息摘要对象是对字节数组进行摘要的,所以先获取字符串的字节数组.

    byte[] bytes = str.getBytes();
    • 1
    • 2
  • 3.信息摘要对象对字节数组进行摘要,得到摘要字节数组:

    byte[] digest = md5.digest(bytes);
    • 1
    • 2
  • 4.把摘要数组中的每一个字节转换成16进制,并拼在一起就得到了MD5值. 
    (PS,有些转换过来得到的是前面有6个f的情况,如:ffffff82,这是因为前面有6组4个1,所以提前把这6组1111先变成0就好了,然后再转16进制就没有f了) 
    (其实也可以在后面续把f去掉)


2.加密文件

方法传入的是文件对象 : file

  • 1.因为是文件不是方法,所以不是像刚才那样通过摘要获取字符串.

  • 2.使用到另一个方法即可:就是信息摘要对象更新:md5.update(byte[] input)方法,用法是通过读取流,不断的更新从流中读到的”信息数组”.

  • 3.然后通过”信息摘要对象”获取摘要,不用参数:md5.digest(),此时返回的数组就已经是包含内容的摘要数组


以下是详细代码:

public class MD5Tool {
public static void main(String[] args) throws Exception {
/*--------------字符串--------------*/
String str = "12345";
String md1 = getMD5(str);
System.out.println(md1);//827ccb0eea8a706c4c34a16891f84e7b /*--------------文件--------------*/
File file = new File("D:\\1.mp3");
String md2 = getMD5(file);
System.out.println(md2);//9068aaead9a5b75e6a54395d8183ec9
}
/**
* 逻辑:
*
* 1.获取md5对象,通过"信息摘要"获取实例构造("MD5").
* 2.md5对象对("字符串的"字节形式"-得到的数组)进行摘要",那么会返回一个"摘要的字节数组"
* 3.摘要字节数组中的"每个二进制值"字节形式,"转成十六进制形式",然后再把这些值给拼接起来,就是MD5值了
* (PS:为了便于阅读,把多余的fff去掉,并且单个字符前加个0)
*
*/
public static String getMD5(String str) throws Exception { String MD5 = ""; MessageDigest md5 = MessageDigest.getInstance("MD5");
byte[] bytes = str.getBytes();
byte[] digest = md5.digest(bytes); for (int i = 0; i < digest.length; i++) {
//摘要字节数组中各个字节的"十六进制"形式.
int j = digest[i];
j = j & 0x000000ff;
String s1 = Integer.toHexString(j); if (s1.length() == 1) {
s1 = "0" + s1;
}
MD5 += s1;
}
return MD5;
}
//重载,所以用户传入"字符串"或者"文件"都可以解决. /**
* 处理逻辑:
* 1.现在传入的是"文件",不是字符串
* 2.所以信息摘要对象.进行摘要得到数组不能像上面获得:md5.digest(bytes),因为不是str.getBytes得到bytes
* 3.其实还是通过mdt.digest();获取到字节数组,但是前期必须要有一个方法必须是md5.update(),即"信息摘要对象"要先更新
* 4."信息摘要更新"里面有(byte[] input),说明是读取流获取到的数组,所以我们就用这个方法.
* 5.所以最终的逻辑就是:
*
* 1.获取文件的读取流
* 2.不停的读取流中的"内容"放入字符串,放一部分就"更新"一部分.直到全部完毕
* 3.然后调用md5.digest();就会得到有内容的字节数组,剩下的就和上边一样了.
*/
public static String getMD5(File file) throws Exception {
String MD5 = ""; MessageDigest md5 = MessageDigest.getInstance("MD5");
FileInputStream fis = new FileInputStream(file); byte[] bytes = new byte[1024 * 5]; int len = -1;
while ((len=fis.read(bytes))!=-1) {
//一部分一部分更新
md5.update(bytes, 0, len);
}
byte[] digest = md5.digest();
for (int i = 0; i <digest.length; i++) {
int n = digest[i] & 0x000000ff;
String s = Integer.toHexString(n); MD5 += s;
}
return MD5;
}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79

拓展

0xfffffff代表的含义:

  • 0x:代表16进制;

  • 一个f代表:4个1,即(1111);

  • 所以0xffffffff代表:8组4个1

    1111 - 1111 - 1111 - 1111 - 1111 - 1111 - 1111 - 1111
    • 1
    • 2
  • 所以刚才的0xffffff82就是前面6组都是1,后面两组是

    1111 - 1111 - 1111 - 1111 - 1111 - 1111 - 0111 - 0010
    • 1
    • 2
  • 所以先与上0x000000ff,即

    0000 - 0000 - 0000 - 0000 - 0000 - 0000 - 1111 - 1111
    • 1
    • 2
  • 就得到了82了

上面的方法也可以写写成:

        for (int i = 0; i < digest.length; i++) {
//摘要字节数组中各个字节的"十六进制"形式.
String s1 = Integer.toHexString( digest[i]); //如果是8个长度的,把前面的6个f去掉,只获取后面的
if (s1.length() == 8) {
s1 = s1.substring(6);
}
if (s1.length() == 1) {
s1 = "0" + s1;
}
MD5 += s1;
} 、、、、、、、、、、、、、、、、、、、、、、、、、
另外,以下转自知乎:https://www.zhihu.com/question/22651987

1+6=7,但是给你个7你能知道这是几跟几加得的吗?

如果有人坚持认为MD5算法是可逆的,请不妨设想一下将MD5算法应用到文件压缩方面,那岂不是又出现了一种超级压缩技术了。。好几个G大小的文件都能压缩成一串MD5,反正"可以求逆"也就是解压缩(如果应用于压缩技术,算法就是公开的了,也不用费劲去破解了)。可惜这个显然是不可能的,哈哈哈哈

作者:知乎用户
链接:https://www.zhihu.com/question/22651987/answer/23110721
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

 
、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、
作者:武杰
链接:https://www.zhihu.com/question/22651987/answer/23079557
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

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

同学的答案中有说到
不过有个地方值得指出的是,一个MD5理论上的确是可能对应无数多个原文的,因为MD5是有限多个的而原文可以是无数多个。比如主流使用的MD5将任意长度的“字节串映射为一个128bit的大整数。也就是一共有2^128种可能,大概是3.4*10^38,这个数字是有限多个的,而但是世界上可以被用来加密的原文则会有无数的可能性。
不过需要注意的一点是,尽量这是一个理论上的有限对无限,不过问题是这个无限在现实生活中并不完全成立,因为一方面现实中原文的长度往往是有限的(以常用的密码为例,一般人都在20位以内),另一方面目前想要发现两段原文对应同一个MD5(专业的说这叫杂凑冲撞)值非常困难,因此某种意义上来说,在一定范围内想构建MD5值与原文的一一对应关系是完全有可能的。所以对于MD5目前最有效的攻击方式就是彩虹表_百度百科,具体详情你可以通过链接了解。
这一段为了方便大家理解,改个老梗作为栗子吧,【世界上只有一个我,但是但是妞却是非常非常多的,以一个有限的我对几乎是无限的妞,所以可能能搞定非常多(100+)的妞,这个理论上的确是通的,可是实际情况下....】

至于怎么样算是在计算过程中原文的部分信息丢失,同时还能起到校验验证的作用,我举个栗子
原文:
快点赞啊亲
加密规则:
每个字取拼音声调+笔画数,最后的结果计算乘积,为了也使得我的结果始终保持在一个限定范围内,取最后结果取其与2^14=16384的余数(随便取的,你们就当我有二进制强迫症吧)
如 快 是7画,4声,也就是“特征值11”,以此类推 点9+3=12 赞16+4=20 啊10+4=14 亲9+1=10
最后我发明的不可逆函数值就是
11*12*20*14*10=26400与16384的余数,也就是10016
如果单单给10016这个数字和加密算法,你是无论如何不可能推倒出原文是“快点赞啊亲”的,不过如果给你“快点赞啊亲”你却很容易验证答案是否正确。

嗯,既然我都已经把我想说的用原文告诉你们了!嗯,就是这样

 
 

MD5加密算法全解析的更多相关文章

  1. 一起谈谈MD5加密算法

    MD5是一个安全的散列算法,输入两个不同的明文不会得到相同的输出值,根据输出值,不能得到原始的明文,即其过程不可逆:所以要解密MD5没有现成的算法,只能用穷举法,把可能出现的明文,用MD5算法散列之后 ...

  2. Google Maps地图投影全解析(3):WKT形式表示

    update20090601:EPSG对该投影的编号设定为EPSG:3857,对应的WKT也发生了变化,下文不再修改,相对来说格式都是那样,可以到http://www.epsg-registry.or ...

  3. C#系统缓存全解析(转载)

    C#系统缓存全解析 对各种缓存的应用场景和方法做了很详尽的解读,这里推荐一下 转载地址:http://blog.csdn.net/wyxhd2008/article/details/8076105

  4. 【凯子哥带你学Framework】Activity界面显示全解析

    前几天凯子哥写的Framework层的解析文章<Activity启动过程全解析>,反响还不错,这说明“写让大家都能看懂的Framework解析文章”的思想是基本正确的. 我个人觉得,深入分 ...

  5. iOS Storyboard全解析

    来源:http://iaiai.iteye.com/blog/1493956 Storyboard)是一个能够节省你很多设计手机App界面时间的新特性,下面,为了简明的说明Storyboard的效果, ...

  6. MD5加密算法

    package com.bao.tools.encryption; import java.security.MessageDigest;import java.security.NoSuchAlgo ...

  7. md5加密算法c语言版

    from: http://blog.sina.com.cn/s/blog_693de6100101kcu6.html 注:以下是md5加密算法c语言版(16/32位) ---------------- ...

  8. 【转载】Fragment 全解析(1):那些年踩过的坑

    http://www.jianshu.com/p/d9143a92ad94 Fragment系列文章:1.Fragment全解析系列(一):那些年踩过的坑2.Fragment全解析系列(二):正确的使 ...

  9. MD5加密算法测试

    在用户注册这一块,密码加密保证客户信息安全是最重要的,在网上查询了一些资料,发现加密算法比较流行的有MD5,DES和SHA. 虽然SHA与MD5通过碰撞法被破解了,但是MD5和SHA仍被公认是安全的加 ...

随机推荐

  1. Redis(十三):Redis分布式锁的正确实现方式

    前言 分布式锁一般有三种实现方式:1. 数据库乐观锁:2. 基于Redis的分布式锁:3. 基于ZooKeeper的分布式锁.本篇博客将介绍第二种方式,基于Redis实现分布式锁.虽然网上已经有各种介 ...

  2. vim资源帖

    vimscript教程 http://learnvimscriptthehardway.stevelosh.com/ 阿信的vimscript http://www.axiaoxin.com/arti ...

  3. 集群中的session共享存储 实现会话保持

    每组web服务器端做一下调整: [root@web03 memcache-2.2.6]# egrep "(session.save_handler|session.save_path)&qu ...

  4. cocos2d-x实例学习之常用类及其概要作用

    CCLayer,CCScene CCLayer类对应cocos2d-x引擎里的布景.每个游戏场景中都可以有很多层,每一层负责各自的任务,例如专门负责显示背景.专门负责显示道具和专门负责显示人物角色等. ...

  5. java中null和""的区别

    问题一: null和""的区别 String s=null; s.trim()就会抛出为空的exception String s=""; s.trim()就不会 ...

  6. mysql 索引 大于等于 走不走索引 最左前缀

    你可以认为联合索引是闯关游戏的设计 例如你这个联合索引是state/city/zipCode 那么state就是第一关 city是第二关, zipCode就是第三关 你必须匹配了第一关,才能匹配第二关 ...

  7. 24 WHEN CAN WE STOP TESTING?

    24 WHEN CAN WE STOP TESTING? 2015-09-25 THERE IS NO simple way of deciding when a system is complete ...

  8. eclipse生成export生成jar详解

    使用eclipse打jar包可能还有很多人不是很了解,今天特意测试整理一番. 打jar包有3种形式 JAR file               JAR Javadoc              ja ...

  9. 深入学习HttpClient(一)扩展额外的功能

    HttpClient作为.net4.5新增的Http库除了对于async/await形式的异步支持外,还向我们展示了其强大的扩展能力. [类库的设计] 让我们先看下Httpclient的设计图: 图中 ...

  10. Idea上配置btm

    1.  先在eclipse中配置好项目,再讲配置好的项目导入到idea中