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. Batch - C:\Progra~1是什么意思

    就是那种DOS下的8.3的规范,可以这样写 C:\Progra~1也可以这样写全名字的 "C:\Program File",因为这个路径中的文件夹名有空格,要用两个英文输入法下的双 ...

  2. [JZOJ4665] 【GDOI2017模拟7.21】数列

    题目 题目大意 给你一个数列,让你找到一个最长的连续子序列,满足在添加了至多KKK个数之后,能够变成一条公差为DDD的等差数列. 思考历程 一眼看上去似乎是一道神题-- 没有怎么花时间思考,毕竟时间都 ...

  3. CSS——滑动门技术及应用

    先来体会下现实中的滑动门,或者你可以叫做推拉门: 滑动门出现的背景 制作网页时,为了美观,常常需要为网页元素设置特殊形状的背景,比如微信导航栏,有凸起和凹下去的感觉,最大的问题是里面的字数不一样多,咋 ...

  4. prometheus配置详情

    https://prometheus.io/docs/prometheus/latest/configuration/configuration/ 下面监控宿主机和容器的内存,CPU,磁盘等状态 gr ...

  5. python 毫秒时间戳转日期

    import time import datetime timestamp = 1570774556514 # 转换成localtime time_local = time.localtime(tim ...

  6. Sublime text2 + cygwin编译C++

    1.安装cygwin2.安装sublime text23.将g++和gdb加入系统环境变量(windows系统)3.安装package control4.通过package control安装subl ...

  7. 51nod-1130-N的阶乘的长度V2(斯特林近似)-套斯特林公式

    输入N求N的阶乘的10进制表示的长度.例如6! = 720,长度为3. 输入 第1行:一个数T,表示后面用作输入测试的数的数量.(1 <= T <= 1000) 第2 - T + 1行:每 ...

  8. 洛谷P1792——[国家集训队]种树

    传送门:QAQQAQ 题意:$n$个点中选$m$个不相邻的点,使得这些点不相邻(1和n算相邻),求这些点的最大值 思路:这不是神仙题不是神仙题…… 刚看到这题觉得不难,好像只要贪心就可以了但贪心不知从 ...

  9. day 81 Vue学习二之vue结合项目简单使用、this指向问题

    Vue学习二之vue结合项目简单使用.this指向问题   本节目录 一 阶段性项目流程梳理 二 vue切换图片 三 vue中使用ajax 四 vue实现音乐播放器 五 vue的计算属性和监听器 六 ...

  10. IO初步,字节输入流和字节输出流

    字节输出流 OutputStream(基类,抽象) 特点:写任意的文件 方法:写出数据的方法:write write(int b) 写出1个字节 -128~127之间,写的是一个ASCLL码的值 wr ...