所谓加盐就是系统随机生成一个字符串,
这个字符串和用户的密码混合到一起进行MD5加密。并在数据库保存这个盐(随机字符串)
当验密的时候,取出盐,再用待验证的密码走一遍加密的过程(这个过程唯一不同的是,盐不是随机的,是取出
之前保存的)。
因为盐都是一样的,如果密码是正确的,那么加密后的密码和数据库存必然是一样的。
这个加盐的过程保证了,注册的时候,因为盐是随机的,所以同样的一个密码,比如111111,每次加密后
的密文是不一样的。(因为混入了盐)
我参考了别人的代码,把盐放入了最终的密码前N位,而不是单独存一个字段。这个不影响整体的算法。
代码:
package com.example.gate.util;
import java.io.UnsupportedEncodingException;
import java.math.BigInteger;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.util.Arrays;
/**
* MD5加盐加密算法
* 4位盐,32位密码共36位长度
*
* @author lsy
*
*/
public class Md5SaltUtil {
public static void main(String[] args) {
//测试加密和验密
for(int i=0;i<3;i++) {
System.out.println("\r\n");
//加密过程---------------
String password = "111111";
String dbpass = Md5SaltUtil.getEncryptedPwd(password);//加密后存放在数据库
System.out.println("#######################");
//验密过程---------------跟数据库密码比对
String passwordValid="111111";//待验证的密码
boolean falg= Md5SaltUtil.validPassword(passwordValid, dbpass);//用待验证的密码 和数据库的密码进行验密
if(falg) {
System.out.println(passwordValid+"验密通过.");
}else {
System.out.println(passwordValid+"验密失败........................");
}
//验密过程---------------跟数据库密码比对
String passwordValidError="111111xxxx";//待验证的密码
boolean falg2= Md5SaltUtil.validPassword(passwordValidError, dbpass);//用待验证的密码 和数据库的密码进行验密
if(falg2) {
System.out.println(passwordValidError+"验密通过.");
}else {
System.out.println(passwordValidError+"验密失败........................");
}
}
}
private static final String HEX_NUMS_STR = "0123456789ABCDEF";
private static final Integer SALT_LENGTH = 2;
private static final boolean isDebug = true;//是否打印debug日志
/**
* 将16进制字符串转换成字节数组
*
* @param hex
* @return
*/
public static byte[] hexStringToByte(String hex) {
int len = (hex.length() / 2);
byte[] result = new byte[len];
char[] hexChars = hex.toCharArray();
for (int i = 0; i < len; i++) {
int pos = i * 2;
result[i] = (byte) (HEX_NUMS_STR.indexOf(hexChars[pos]) << 4 | HEX_NUMS_STR.indexOf(hexChars[pos + 1]));
}
return result;
}
// private static byte[] fromHex(String hex)
// {
// byte[] binary = new byte[hex.length(