MD5加密工具类&MessageDiges简介

这里写目录标题

  • 一:MessageDigest
  • 二:方法介绍
  • 三、MessageDigest 实例创建
  • 四:工具类编写
    • 读取配置文件工具类
    • MD5加密工具类

MD5
  全称是Message-Digest Algorithm 5(信息-摘要算法5),理论上是一种单向的哈希散列,

特性:

输入任意长度的信息,经过处理,输出为128位的大整数(数字指纹)(32位16进制数); 不同的输入一般得到不同的结果(唯一性);
根据128位的输出结果不可能反推出输入的信息(不可逆); 强抗碰撞:想找到两个不同的数据,使它们具有相同的MD5值,是非常困难的。

在实现MD5工具类时,需要借助一个类MessageDigest产生哈希映射值,先对该类进行简要介绍。

一:MessageDigest

MessageDigest 类为应用程序提供信息摘要算法的功能,如 MD5 或 SHA 算法。信息摘要是安全的单向哈希函数,它接收任意大小的数据,输出固定长度的哈希值。

MessageDigest 对象开始被初始化。该对象通过使用 update 方法处理数据。任何时候都可以调用 reset 方法重置摘要。一旦所有需要更新的数据都已经被更新了,应该调用 digest 方法之一完成哈希计算。
对于给定数量的更新数据,digest 方法只能被调用一次。digest 被调用后,MessageDigest 对象被重新设置成其初始状态。

二:方法介绍

1public static MessageDigest getInstance(String algorithm)
                                 throws NoSuchAlgorithmException
   返回实现指定摘要算法的 MessageDigest 对象。
   algorithm - 所请求算法的名称
2public static MessageDigest getInstance(String algorithm,String provider)throwsNoSuchAlgorithmException,NoSuchProviderException
  返回实现指定摘要算法的 MessageDigest 对象。
  algorithm - 所请求算法的名称
  provider - 提供者的名称。
3public void update(byte[] input)
  使用指定的 byte 数组更新摘要。
4public byte[] digest()
  通过执行诸如填充之类的最终操作完成哈希计算。在调用此方法之后,摘要被重置。
5public static boolean isEqual(byte[] digesta,
                              byte[] digestb)
比较两个摘要的相等性。做简单的字节比较。

三、MessageDigest 实例创建

3.1、创建 MessageDigest 对象

计算信息摘(即散列码)要做的第一步是创建 MessageDigest对象 实例。像所有的引擎类一样,获取某类报文摘要算法(即散列算法,比如MD5)的 MessageDigest 对象的途径是调用 MessageDigest 类中的 getInstance 静态 factory 方法:

public static MessageDigest getInstance(String algorithm)

注意:算法名不区分大小写。例如,以下所有调用都是相等的:

MessageDigest.getInstance("SHA");
 
MessageDigest.getInstance("sha");
 
MessageDigest.getInstance("sHa");

调用程序可选择指定提供者名称,以保证所要求的算法是由已命名提供者实现的:

public static MessageDigest getInstance(String algorithm, String provider);

调用 getInstance 将返回已初始化过的MessageDigest对象。因此,它不需要进一步的初始化。

3.2、向MessageDigest传送要计算的数据

计算数据的摘要的第二步是向已初始化的MessageDigest对象提供传送要计算的数据。这将通过一次或多次调用以下某个 update(更新)方法来完成:

public void update(byte input);
 
public void update(byte[] input);
 
public void update(byte[] input, int offset, int len);

3.3、计算摘要

通过调用 update 方法向MessageDigest对象提传送要计算的数据后,你就可以调用以下某个 digest(摘要)方法来计算摘要(即生成散列码):

public byte[] digest();
 
public byte[] digest(byte[] input);
 
public int digest(byte[] buf, int offset, int len);

四:工具类编写

MD5破解:是使用穷举法来进行破解。
如:我们计算出键盘上所有字符的组合的md5,将加密前后的字符串分别存入数据库中;然后拿你的md5加密后的字符串进行查询得出加密前的字符串。

*预防措施

  1. 多次对数据进行MD5加密
  2. 在数据加密时加上特殊的后缀信息,这样生成的密文就是对于: 原始数据 + 自定义秘钥信息。此时在不知道秘钥信息的前提下是很难破解的。

本工具类基于第二种方式提供的加密策略

配置文件信息:

 password.salt = Ambitonsdafaqj23ou89ZXcj@#$@#$#@KJdjklj;D../dSF.,`

读取配置文件工具类

主要作用在于读取配置文件中提供的password.salt的信息内容,主要是避免硬编码的形式,便于后续维护所考虑,如果单纯为了测试,可以直接写到代码中,根据实际情况进行选择。

/***
	
***/
public class PropertiesUtil {
     


    private static Properties props;

    // 静态初始化
    static {
     
        String fileName = "配置文件文件名.properties";
        // 实例化一个对象后,装载内容
        props = new Properties();
        InputStream inputStream = PropertiesUtil.class.getClassLoader().getResourceAsStream(fileName);
        try {
     
        // 装载内容
            props.load(inputStream);
        } catch (IOException e) {
     
            e.printStackTrace();
        }
    }
    public static String getProperty(String key,String defaultValue){
     

        String value = props.getProperty(key.trim());
        if(StringUtils.isBlank(value)){
     
            value = defaultValue;
        }
        return value.trim();
    }

    private static String getProperty(String key) {
     
        String value = props.getProperty(key.trim());
        if (StringUtils.isBlank(value)) {
     
            return null;
        }
        return value.trim();
    }

}

MD5加密工具类

/**
 * @description MD5工具类
 * @create: 2020-07-22 17:58
 **/
public class MD5Util {
     

    private static final String hexDigits[] = {
     "0", "1", "2", "3", "4", "5",
            "6", "7", "8", "9", "a", "b", "c", "d", "e", "f"};
    /**
     *  返回加密后的信息内容string
     * @param origin
     * @return
     */
    public static String MD5EncodeUtf8(String origin) {
     
        // 获取后缀信息
        origin = origin + PropertiesUtil.getProperty("password.salt", "");
        return MD5Encode(origin, "utf-8");
    }

    private static String MD5Encode(String origin, String charsetname) {
     
        String resultString = null;
        try {
     
            MessageDigest md = MessageDigest.getInstance("MD5");
            if(charsetname == null || "".equals(charsetname)){
     
                // 默认编码信息格式处理  默认格式为utf-8编码处理
                resultString = byteArrayToHexString(md.digest(origin.getBytes()));
            }else{
     
                // 主要为了应该不同信息的编码
                resultString = byteArrayToHexString(md.digest(origin.getBytes(charsetname)));
            }
        }catch (Exception exception){
     
            throw new RuntimeException("无法获取加密算法");
        }
        // 全部转成大写
        return resultString.toUpperCase();
    }

    private static String byteArrayToHexString(byte[] digest) {
     
        StringBuilder resultString = new StringBuilder();
        for( int i = 0 ; i <digest.length;  i ++ ) {
     
            resultString.append(byteToHexString(digest[i]));
        }
        return resultString.toString();
    }

    /***
     * 对单个字符进行加密处理
     * @param b
     * @return
     */
    private static String byteToHexString(byte b) {
     

        int  n = b;
        // 注意:此时进行映射时,数据会转成byte形式  byte数据范围在 -128 - 127
        // 由于对16取模,加256后变成整数,并不影响数据
        if ( n < 0) {
     
            n += 256;
        }
        // 获取字符下标信息
        int d1 = n / 16;
        int d2 = n % 16;

        //返回信息
        return hexDigits[d1] + hexDigits[d2];
    }

}

你可能感兴趣的:(java,java)