ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

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

2019-05-07 22:50:45  阅读:254  来源: 互联网

标签:输出 加密 Java10 1MD5 算法 new byte 输入 String


摘要算法

摘要算法(哈希算法/Hash/数字指纹):

  • 计算任意长度数据的摘要(固定长度)
  • 相同的输入数据始终得到相同的输出
  • 不同的输入尽量得到不同的输出

摘要算法目的:

  • 验证原始数据是否被篡改

输入:任意长度数据(byte[])
输出:固定长度数据(byte[n])
hash("hello") = 0x5e918d2
hash("hello,java") = 0x7a9d88e8
hash("hello,bob") = 0xa0dbae2f
java的Object.hashCode()方法就是一个摘要算法:
输入:任意数据
输出:固定长度数据(int, byte[4])
相同的输入得到相同的输出:equals/hashCode

碰撞:
两个不同的输入得到了相同的输出,仅做示例

    hash("abc") = 0x12345678 
    hash("xyz") = 0x12345678

哈希算法是将一个无限的输入集合映射到一个有限的输入集合。碰撞是不能避免的,因为输出的字节长度是固定的,而输入的字节长度是不固定的。所以哈希算法是把一个无限的输入集合映射到一个有限的输出集合。
假设输出2个字节的摘要,1个字节8位,2个字节16位,即所有的输出在16个0到16个1之间,即2^16=65536。将无限的输入映射到输出集合中,肯定有不同的输入获得相同输出的情况,即碰撞。

Hash算法的安全性:

  • 好的Hash算法,碰撞率要低
  • 好的Hash算法,不能根据输入猜测输出
    * 如hashA("java001") = "123456",hashA("java002") = "123457"。可能推出hashA("java003") = "123458"
  • 好的Hash算法,输入的任意一个bit的变化会造成输出完全不同
    * 如hashA("java001") = "123456",hashA("java002") = "580645"。可能推出hashA("java003") = ?
  • 很难从输出反推输入(只能暴力穷举)
    常用的摘要算法:
算法 输出长度:位数 输出长度:字节数
MD5 128 bits 16bytes
SHA-1 160bits 20bytes
SHA-256 256bits 32bytes
PipeMd-160 160bits 20bytes
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)));
    }
}

总结:

  • MD5是一种常用的哈希算法,输出128bits/16bytes
  • 常用于验证数据完整性
  • 用于存储口令时要考虑彩虹表攻击

标签:输出,加密,Java10,1MD5,算法,new,byte,输入,String
来源: https://www.cnblogs.com/csj2018/p/10828688.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有