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. LCD Common电压

    因为驱动液晶翻转靠的是两个玻璃电极上的电压差,而电压差是由电容提供的,电容一端接到S基,另一端接到一个基准电压上,这个电压就是Common电压.

  2. 软件设计师_朴素模式匹配算法和KMP算法

    1.从主字符串中匹配模式字符串(暴力匹配) 2. KMP算法

  3. CentOS7的mysql5.7-rpm.bundle方式安装

    下载地址 https://dev.mysql.com/get/Downloads/MySQL-5.7/mysql-5.7.19-1.el6.x86_64.rpm-bundle.tar 查询mariad ...

  4. VS开发工具的常用插件

    转 http://www.spersky.com/post/vsPlugins.html 我目前主要用的是Hide Main Page——公司配给的电脑屏幕分辨率好小,还是1366*768的,去掉头可 ...

  5. System.Drawing.Imaging.ImageFormat.cs

    ylbtech-System.Drawing.Imaging.ImageFormat.cs 1.程序集 System.Drawing, Version=4.0.0.0, Culture=neutral ...

  6. vuex的简单介绍

    .vuex的定义 )Vuex 是一个专门为 Vue.js 应用程序开发的状态管理模式,使用插件的形式引进项目中 )集中存储和管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化 ...

  7. 一些关于Hibernate延迟加载的误区

    最近面试别人,正好出的笔试题中有道关于Hibernate延迟加载的问题,聊天过程中发现很多人对Hibernate的延迟加载有些理解误区,写 些东东在这里,希望对大家有所帮助. 首先是第一个误区:延迟加 ...

  8. 国外主机如何ICP备案

    想都不要想了,无法备案. 因为,备案是在主机服务器提供商处的备案平台提交申请,国外的主机服务商是没有这种平台服务的.(跟你域名在哪儿买的没关系) 下面,把昨天折腾到半夜的过程记录一下,希望可以帮到需要 ...

  9. vue-router使用入门

    安装及基本配置 # 安装 npm install vue-router # 使用 import Vue from 'vue' import VueRouter from 'vue-router' Vu ...

  10. <day005>jQuery事件、文档基本操作 + 点赞事件

    任务1: jQuery的基本操作 <!DOCTYPE html> <html lang="zh-CN"> <head> <meta cha ...