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的更多相关文章

  1. 廖雪峰Java10加密与安全-3摘要算法-5Hmac

    1 比较MD5和HamcMD5 HmacMD5可以看作带安全salt的MD5 import javax.crypto.KeyGenerator; import javax.crypto.Mac; im ...

  2. 廖雪峰Java10加密与安全-3摘要算法-4BouncyCastle

    1.BouncyCastle: 第三方提供的一组加密/哈希算法 提供JDK没有提供的算法 RipeMD160哈希算法 官方网站 2.如何使用第三方提供的算法 2.1 添加第三方jar至classpat ...

  3. 廖雪峰Java10加密与安全-3摘要算法-3SHA-1算法

    1.SHA-1算法 SHA-1算法也是一种哈希算法. 输出160 bits/20bytes 由美国国家安全局开发 SHA-0/SHA-1/SHA-256/SHA-512 * SHA-0有问题,已经作废 ...

  4. 廖雪峰Java10加密与安全-6数字证书-1数字证书

    数字证书: 非对称加密算法:对数据进行加密/解密 签名算法:确保数据完整性和抗否认性 摘要算法:确保证书本身没有被篡改

  5. 廖雪峰Java10加密与安全-5签名算法-1RSA签名算法

    1.数字签名 甲在发送加密消息的时候,还要发送自己的签名,而这个签名是用甲的privateKey计算的:而乙要验证这个签名是否是合法的,会用甲的publicKey去验证,如果验证成功,这个消息确实是甲 ...

  6. 廖雪峰Java10加密与安全-4加密算法-5非对称加密算法

    1.非对称加密 非对称加密就是加密和解密使用的不是相同的密钥 方法1: * 加密:用自己的私钥加密,然后发送给对方:encrypt(privateKeyA, message)->s * 解密:对 ...

  7. 廖雪峰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 ...

  8. 廖雪峰Java10加密与安全-4加密算法-2口令加密算法

    对称加密key是一个byte数组,如AES256算法的key是一个32字节的数组,普通的加密软件由用户输入加密口令.如果由用户输入口令,进行加密/解密,需要用到PBE算法. 1.PBE:Passwor ...

  9. 廖雪峰Java10加密与安全-4加密算法-1对称加密算法

    1.对称加密算法 加密和解密使用同一个密钥,例如WinRAR. WinRAR在对文件进行打包的时候,可以设置一个密码,在解压的时候需要使用同样的密码才能正确的解压. 加密:encrypt(key,me ...

随机推荐

  1. 【JZOJ6376】樱符[完全墨染的樱花]

    description analysis 无向图上任意两点最大流不超过\(2\),说明该图是仙人掌 由于最大流等于最小割,如果一条边在两个环里,断掉两个端点至少需要\(3\)的代价 对于该仙人掌,求两 ...

  2. oracle将查询结果横转纵

    SELECT '残疾人|民政|综合治理|计划生育|物业监管|安全生产|环境类|司法信访|党建|社会组织|文化体育|社保' D , '53|52|51|50|49|48|47|5|4|3|2|1' g ...

  3. Eclipse中servlet简易模版

    package ${enclosing_package}; import java.io.IOException; import javax.servlet.ServletException; imp ...

  4. (转)iframe 高度100%时,出现垂直滚动条

    问题 需求是这样的,iframe在一个div中,并且iframe高度与div一样,所以设置了iframe高度是100%,结果div出现了滚动条,在排除了padding.margin的因素外,还是有滚动 ...

  5. 适AT maven多个子项目、父项目之间的引用问题

    适AT   maven多个子项目.父项目之间的引用问题 在项目时用到maven管理项目,在一个就项目的基础上开发新的项目:关于子项目和父项目,子项目与子项目之间的调用问题,发现自己存在不足,以下是自己 ...

  6. 操作系统-Windows操作系统的线程调度了解这些

    Windows操作系统支持内核级线程,调度单位是线程,它采用基于动态优先级的,抢占式调度,并结合时间配额的调整来完成调度 一.几个前提知识点 就绪线程按优先级进入相应的就绪队列 系统总是选择优先级最高 ...

  7. 微信小程序(mpvue框架) 购物车

    效果图: 说明:全选/全不选, 1.数据: products:[{checked:true,code:"4",echecked:false,hasPromotions:true,i ...

  8. 1.1_springboot2.x与缓存原理介绍&使用缓存

    一.springboot与缓存介绍&使用缓存 1.JSR107 JAVA Cahing定义了5个核心接口,分别是CachingProvider.CacheManager.Cache.Entry ...

  9. <每日一题>题目14:拷贝的问题

    ''' 拷贝的问题 引用:无论怎么变都一起变 浅拷贝:只拷贝父对象,不会拷贝父对象中的子对象 深拷贝:完全拷贝,重新划分内存空间 ''' 具体如下图: 题目: #求a.b.c.d的值 import c ...

  10. jQuery链式编程时修复断开的链

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...