最近经常听到各大平台数据泄露 而且使用的MD5加密算法 网络上也会有各种进行MD5解密的网站。那么问题来了 是否说MD5就不实用了呢,
其实不是的,只要加密规则适当 MD5的可靠性还是很高的。 下面就通过代码来体现:
1.工具类 生成一个32位的随机数
package com.bjsxt.yxl.common.util;
import java.util.Random;
import org.springframework.stereotype.Component;
/**
* 所有正则表达式的工具类
* @author wangshSxt
*
*/
@Component("regexUtil")
public class RegexUtil
{
private String souString = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" ;
/**
* 生成随机数
* @return
*/
public String randStr(int length)
{
/* 存储所有的结果 */
StringBuffer sb = new StringBuffer();
Random random = new Random();
for(int i = 0 ; i < length ; i ++ )
{
/* 生成20以内的随机数 (0-->19) */
/* 生成随机字符串长度的下标值 */
int res = random.nextInt(souString.length());
char ch = souString.charAt(res);
sb.append(ch);
}
return sb.toString() ;
}
public static void main(String[] args)
{
RegexUtil regexUtil = new RegexUtil();
String result = regexUtil.randStr(4);
System.out.println(result);
}
}
2. MD5原生加密规则 以及改进后的加密规则 and 测试代码
package com.bjsxt.yxl.common.util;
import java.security.MessageDigest;
import java.util.Arrays;
/**
* 加密算法的工具类
*
* @author wangshSxt
*
*/
public class EncryptUtil
{
/**
* md5算法
* @param s
* @return
*/
public static String MD5(String s)
{
char hexDigits[] =
{ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
try
{
byte[] btInput = s.getBytes();
// 获得MD5摘要算法的 MessageDigest 对象
MessageDigest mdInst = MessageDigest.getInstance("MD5");
// 使用指定的字节更新摘要
mdInst.update(btInput);
// 获得密文
byte[] md = mdInst.digest();
// 把密文转换成十六进制的字符串形式
int j = md.length;
char str[] = new char[j * 2];
int k = 0;
for (int i = 0; i < j; i++)
{
byte byte0 = md[i];
str[k++] = hexDigits[byte0 >>> 4 & 0xf];
str[k++] = hexDigits[byte0 & 0xf];
}
return new String(str);
} catch (Exception e)
{
e.printStackTrace();
return null;
}
}
/**
* 密码加密:
* 目的:让存储在数据库中的密码始终不一样;即使明文一样,密文也不一样;
*
* 加密明文:$MD5+$随机数+$密码明文
* 加密后的密文:$MD5$随机数$ Md5($MD5+$随机数+$明文)
*
*
* @param souPass
* @return
*/
public static String encodePass(String souPass)
{
RegexUtil regexUtil = new RegexUtil();
/* 先拼装明文 */
String preSb = "$MD5" ;
String random = regexUtil.randStr(32) ;
preSb += "$" + random ;
String jiamiQian = preSb + "$" + souPass ;
/* 将字符串加密
* jiamiQian:
* $MD5+$随机数+$明文
* $MD5$BKZaFzf6UCH76ru0wa3CdkMxdt156ECQ$11111
* */
String jiamiHou = EncryptUtil.MD5(jiamiQian);
System.out.println(jiamiHou + "========>" + jiamiQian);
/*
* $MD5$随机数$ Md5($MD5+$随机数+$明文)
* */
String dbStr = preSb + "$" + jiamiHou ;
return dbStr ;
}
/**
* 验证两个明文和官方是否一一对应
*
* 将待验证的密码,按照加密的规则重新拼装一遍,比较两次加密后的密码是否一致;
*
* @param souPass 明文(待验证的密码)
* @param encodePass 加密后的密码:如 $MD5$wIdRcNJe1bnCZqX8nGJsLNiiXlq2ePTS$0D1C0A387FA001B1C9E719E539810096
* @return
*/
public static boolean checkPass(String souPass,String encodePass)
{
/* 获取密码明文,从数据库中存储的密文取出md5和随机数,统一再走一遍加密流程,
* 比较两个密文
* */
/* 取得加密算法和随机数 */
String[] encodePasses = encodePass.split("\\$");
//System.out.println(Arrays.toString(encodePasses));
String preSb = "$" + encodePasses[1] + "$" + encodePasses[2] + "$";
/* $MD5$oXr8OW0h71y4FUbjKgdP3bLF3F8WIX9a$111111 */
String jiamiQian = preSb + souPass ;
/* 814087ED1E811D381AA18F07D1A24180 */
String jiamiHou = EncryptUtil.MD5(jiamiQian);
/* 数据库存储的字段串 */
String dbStr = preSb + jiamiHou ;
//System.out.println(dbStr + "=========");
//System.out.println(encodePass + "=====");
return dbStr.equals(encodePass) ;
}
public static void main(String[] args)
{
/* 加密字符串 */
String souPass = "111111" ;
String dbStr = EncryptUtil.encodePass(souPass);
System.out.println("----" + dbStr);
/* 验证: */
String encodePass = "$MD5$9NK7D28dUltgzfTTjRmqoQzEPMTtDvAz$D246EDFCE76348393E8D23B68684CE67" ;
boolean flag = EncryptUtil.checkPass(souPass, dbStr);
System.out.println("======" + flag);
}
}