MD5加密
md5加密 明文 加密变成 128位二进制 --> 32位16进制字符串的密文
MD5特征:
- 明文一样, 得到密文一样
- 密文一样, 推出明文一样
- 明文不一样, 得到密文不一样
缺点:
现在网上有很多暴力破解的网址,直接使用md5加密还是不太安全
为了提高安全性,让相同的明文,得到不同的密文
实现方式:通过md5获得的密文+随机字符串+组合两个字符串=实现相同明文,得到不同密文
一般管这个随机字符串叫:盐值
数据库中存储的密码,是经过加密加盐的值
登录验证:
为了将明文加密成密文,就需要将数据库中密文的盐值提取出来,然后将明文md5加密,再和盐值组合在一起,就能得到和数据库中密文一样的值(输入的密码正确)
代码展示
(盐值和组合规则的复杂程度,可以决定密文的复杂程度)
/**
* @param password : 密码明文
* 生成含有随机盐的密码
*/
public static String generate(String password) {
Random r = new Random();
//sb盐值 16位
StringBuilder sb = new StringBuilder(16);
sb.append(r.nextInt(99999999)).append(r.nextInt(99999999));
int len = sb.length();
if (len < 16) { //不够16位,前面补0
for (int i = 0; i < 16 - len; i++) {
sb.append("0");
}
}
String salt = sb.toString();
//密码明文 + 盐值 使用md5加密
password = md5Hex(password + salt); //32位的16进制
char[] cs = new char[48];
//往密文插入盐值
for (int i = 0; i < 48; i += 3) {
cs[i] = password.charAt(i / 3 * 2); //0
char c = salt.charAt(i / 3); //0
cs[i + 1] = c; //cs[1] = 盐值1
cs[i + 2] = password.charAt(i / 3 * 2 + 1);
}
return new String(cs);
}
/**
* 校验密码是否正确
* @param password: 明文
* @param md5: 数据库密文
*/
public static boolean verify(String password, String md5) {
char[] cs1 = new char[32];
char[] cs2 = new char[16];
for (int i = 0; i < 48; i += 3) {
cs1[i / 3 * 2] = md5.charAt(i);
cs1[i / 3 * 2 + 1] = md5.charAt(i + 2);
cs2[i / 3] = md5.charAt(i + 1);
}
String salt = new String(cs2);
// (明文+盐值) 密文 与密文比较
return md5Hex(password + salt).equals(new String(cs1));
}
/**
* 获取十六进制字符串形式的MD5摘要
*/
public static String md5Hex(String src) {
try {
//得到消息摘要对象
MessageDigest md5 = MessageDigest.getInstance("MD5");
//通过md5算法, 把src字符串, 加密成128位二进制
byte[] bs = md5.digest(src.getBytes());
//把128位二进制转换为16进账
return new String(new Hex().encode(bs));
} catch (Exception e) {
return null;
}
}