廖雪峰Java10加密与安全-3摘要算法-1MD5
1.摘要算法
1.1 摘要算法(哈希算法/Hash/数字指纹):
- 计算任意长度数据的摘要(固定长度)
- 相同的输入数据始终得到相同的输出
- 不同的输入尽量得到不同的输出
1.2 摘要算法目的:
- 验证数据和原始数据是否一致,被篡改
1.3.java的Object.hashCode()方法就是一个摘要算法:
- 输入:任意数据
- 输出:固定长度数据(int, byte[4])
- 相同的输入得到相同的输出:重写equals方法时,也要正确的复写hashCode方法。
1.4.碰撞
两个不同的输入得到了相同的输出,仅做示例
hash("abc") = 0x12345678
hash("xyz") = 0x12345678
原因:哈希算法是将一个无限的输入集合映射到一个有限的输入集合。碰撞是不能避免的,因为输出的字节长度是固定的,而输入的字节长度是不固定的。所以哈希算法是把一个无限的输入集合映射到一个有限的输出集合。
假设输出2个字节的摘要,1个字节8位,2个字节16位,即所有的输出在16个0到16个1之间,即2^16=65536。将无限的输入映射到输出集合中,肯定有不同的输入获得相同输出的情况,即碰撞。
1.5 Hash算法的安全性:
一个好的Hash算法:
- 碰撞率要低
- 不能根据输入猜测输出
* 如hashA("java001") = "123456",hashA("java002") = "123457"。可能推出hashA("java003") = "123458" - 输入的任意一个bit的变化会造成输出完全不同
* 如hashA("java001") = "123456",hashA("java002") = "580645"。可能推出hashA("java003") = ? - 很难从输出反推输入(只能暴力穷举)
1.6 常用的摘要算法:
| 算法 | 输出长度:位数 | 输出长度:字节数 |
|---|---|---|
| MD5 | 128 bits | 16bytes |
| SHA-1 | 160bits | 20bytes |
| SHA-256 | 256bits | 32bytes |
| PipeMd-160 | 160bits | 20bytes |
2 MD5算法
Java使用MD5非常简单
//示例代码
import java.security.MessageDigest;
...
MessageDigest md = new MessageDigest.newInstance("MD5");
//反复调用update输入数据
md.update(data1);
md.update(data2);
...
byte[] result = md.digest();//获取长度为16的byte数组
输入数据可以分片操作
import java.security.MessageDigest;
import java.util.Arrays;
public class SplitString {
public static void main(String[] args) throws Exception{
getMD5("helloworld");
String[] ss = {"hello","world"};
getMD5(ss);
}
static void getMD5(String s) throws Exception{
MessageDigest md = MessageDigest.getInstance("MD5");
md.update(s.getBytes());
byte[] result = md.digest();
System.out.println(Arrays.toString(result));
}
static void getMD5(String[] s) throws Exception{
MessageDigest md = MessageDigest.getInstance("MD5");
for(String si:s){
md.update(si.getBytes());
}
byte[] result = md.digest();
System.out.println(Arrays.toString(result));
}
}

2.1 MD5用途
- 验证文件完整性
- MD5存储用户口令
- 系统不存储用户原始口令
- 系统存储用户原始口令的MD5
如何判断用户口令是否正确
- 系统计算用户输入的原始口令的MD5并与数据库存储的MD5对比
* 相同:口令正确
* 不相同:口令错误
使用MD5要注意防止彩虹表攻击

抵御彩虹表攻击:
- 对每个口令额外添加随机数salt
* md5(password)
* md5(salt+password)
3.代码示例
import java.math.BigInteger;
import java.security.MessageDigest;
public class SplitString {
public static byte[] toMD5(byte[] input){
MessageDigest md;
try{
md = MessageDigest.getInstance("MD5");
}catch (Exception e){
throw new RuntimeException(e);
}
md.update(input);
return md.digest();//返回MD5
}
public static void main(String[] args) throws Exception {
String s = "MD5摘要算法测试";
byte[] r = toMD5(s.getBytes("UTF-8"));//先将字符串转化为字节数组
System.out.println(String.format("%032x",new BigInteger(1,r)));
System.out.println(String.format("%040x",new BigInteger(1,r)));//不足40位,前面补0
System.out.println(String.format("%40x0",new BigInteger(1,r)));//后面加0
}
}

import java.math.BigInteger;
import java.security.MessageDigest;
public class SplitString {
public static byte[] toMD5(byte[] input){
MessageDigest md;
try{
md = MessageDigest.getInstance("MD5");
}catch (Exception e){
throw new RuntimeException(e);
}
md.update(input);
return md.digest();//返回MD5
}
public static void main(String[] args) throws Exception {
String s = "helloworld";
String salt = "Random salt";
byte[] r = toMD5((salt+s).getBytes("UTF-8"));//先将字符串转化为字节数组
System.out.println(String.format("%032x",new BigInteger(1,r)));
System.out.println(String.format("%040x",new BigInteger(1,r)));
System.out.println(String.format("%40x0",new BigInteger(1,r)));
}
}

4.总结:
- MD5是一种常用的哈希算法,输出128bits/16bytes
- 常用于验证数据完整性
- 用于存储口令时要考虑彩虹表攻击
廖雪峰Java10加密与安全-3摘要算法-1MD5的更多相关文章
- 廖雪峰Java10加密与安全-3摘要算法-5Hmac
1 比较MD5和HamcMD5 HmacMD5可以看作带安全salt的MD5 import javax.crypto.KeyGenerator; import javax.crypto.Mac; im ...
- 廖雪峰Java10加密与安全-3摘要算法-4BouncyCastle
1.BouncyCastle: 第三方提供的一组加密/哈希算法 提供JDK没有提供的算法 RipeMD160哈希算法 官方网站 2.如何使用第三方提供的算法 2.1 添加第三方jar至classpat ...
- 廖雪峰Java10加密与安全-3摘要算法-3SHA-1算法
1.SHA-1算法 SHA-1算法也是一种哈希算法. 输出160 bits/20bytes 由美国国家安全局开发 SHA-0/SHA-1/SHA-256/SHA-512 * SHA-0有问题,已经作废 ...
- 廖雪峰Java10加密与安全-6数字证书-1数字证书
数字证书: 非对称加密算法:对数据进行加密/解密 签名算法:确保数据完整性和抗否认性 摘要算法:确保证书本身没有被篡改
- 廖雪峰Java10加密与安全-5签名算法-1RSA签名算法
1.数字签名 甲在发送加密消息的时候,还要发送自己的签名,而这个签名是用甲的privateKey计算的:而乙要验证这个签名是否是合法的,会用甲的publicKey去验证,如果验证成功,这个消息确实是甲 ...
- 廖雪峰Java10加密与安全-4加密算法-5非对称加密算法
1.非对称加密 非对称加密就是加密和解密使用的不是相同的密钥 方法1: * 加密:用自己的私钥加密,然后发送给对方:encrypt(privateKeyA, message)->s * 解密:对 ...
- 廖雪峰Java10加密与安全-4加密算法-4密钥交换算法
1DH算法 1.1.原根公式:g^i mod P 条件:1<g<P,0<i<P 原根:介于[1, p-1]之间的任意2个数i,j(p为素数,i≠j)的结果不相等,即 g^i m ...
- 廖雪峰Java10加密与安全-4加密算法-2口令加密算法
对称加密key是一个byte数组,如AES256算法的key是一个32字节的数组,普通的加密软件由用户输入加密口令.如果由用户输入口令,进行加密/解密,需要用到PBE算法. 1.PBE:Passwor ...
- 廖雪峰Java10加密与安全-4加密算法-1对称加密算法
1.对称加密算法 加密和解密使用同一个密钥,例如WinRAR. WinRAR在对文件进行打包的时候,可以设置一个密码,在解压的时候需要使用同样的密码才能正确的解压. 加密:encrypt(key,me ...
随机推荐
- 软件设计师_朴素模式匹配算法和KMP算法
1.从主字符串中匹配模式字符串(暴力匹配) 2. KMP算法
- HDU-1852-Beijing 2008-一个神奇的公式求逆元
As we all know, the next Olympic Games will be held in Beijing in 2008. So the year 2008 seems a lit ...
- java.nio.file.FileSystemException: D:\kafka_2.12-2.1.0\kafka_2.12-2.1.0\logs\__consumer_offsets-30\00000000000000000000.timeindex.cleaned: 另一个程序正在使用此文件,进程无法访问。
在启动kafka时候报错: java.nio.file.FileSystemException: D:\kafka_2.12-2.1.0\kafka_2.12-2.1.0\logs\__consume ...
- LINUX挂接移动硬盘
对linux系统而言,USB接口的移动硬盘是当作SCSI设备对待的.插入移动硬盘之前,应先用fdisk –l 或 more /proc/partitions查看系统的硬盘和硬盘分区情况. [root ...
- Python全栈开发:递归实例
#!/usr/bin/env python # -*- coding;utf-8 -*- """ 递归不能无限,python会限制递归深度,递归主要用于费布拉切数列 &q ...
- python中遇到的问题:IndentationError: unexpected indent
在Python中写下列代码的时候,出现错误:IndentationError: unexpected indent 分析:IndentationError是缩进的错误,查看源代码发现names开始的这 ...
- Spring Boot 配置 Security 密码加密
依赖 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spri ...
- thinkphp 参数绑定
参数绑定是指绑定一个参数到预处理的SQL语句中的对应命名占位符或问号占位符指定的变量,并且可以提高SQL处理的效率,需要数据库驱动类的支持,目前只有PDO和Sqlsrv驱动支持参数绑定功能. 富瑞华大 ...
- Django实现简单的图书管理系统
目录 Django写图书管理系统 功能截图 创建Django项目 开始项目 配置文件 建立路由关系 开始写Django项目 编写核心逻辑函数 写前端页面 add_author.html add_boo ...
- springboot与任务(定时任务)
描述: 项目开发中经常需要执行一些定时任务,比如需要在每天凌晨时候,分析一次前一天的日志信息.Spring为我们提供了异步执行任务调度的方式,提供TaskExecutor .TaskScheduler ...