附加(目前MD5,还有用RSA,速度稍慢,安全性更好)
关于加盐算法做了些自己的总结,
数据库中保存用户的密码,这些东西是很重要的。开发人员和内部认识如果获取到数据库,则很轻易的就得到大量密码信息。
因为目前MD5的数据量已经非常庞大了,如果只是简单的MD5加密,一些技术人员很容易通过反向查询摘要破解密码,为了安
全问题,我们可以对MD5摘要结果加入额外的信息,通常称作加盐。加盐只是对密码做了进一步的安全处理,对获取到加盐算
法的人同样是无效的,因为他可以很轻松的反向破解。
一个简单的加盐算法(转):
每次保存密码到数据库时,都生成一个随机16位数字,将这16位数字和密码相加再求MD5摘要,然后再摘要中再将16位数
字按照规则形成一个48位的字符串,再验证密码时再从48位字符串中按规则提取16位数字,和用户输入的密码相加再
MD5. 按这种方法形成的结果不能直接反查。且容易个密码每次保存时形成的摘要都是不同的。
package com.zving.framework.security;
import java.security.MessageDigest;
import java.util.Random;
import org.apache.commons.codec.binary.Hex;
/**
* @author wyuch
* @email wyuch@zving.com
* @date 2011-12-31
*/
public class PasswordUtil {
/**
* 生成含有随机盐的密码
*/
public static String generate(String password) {
int i1 = new Random().nextInt(99999999);
int i2 = new Random().nextInt(99999999);
String salt = String.valueOf(i1) + String.valueOf(i2);
if (salt.length() < 16) {
for (int i = 0; i < 16 - salt.length(); i++) {
salt += "0";
}
}
password = md5Hex(password + salt);
char[] cs1 = password.toCharArray();
char[] cs2 = salt.toCharArray();
char[] cs = new char[48];
for (int i = 0; i < 48; i += 3) {
cs[i] = cs1[i / 3 * 2];
cs[i + 1] = cs2[i / 3];
cs[i + 2] = cs1[i / 3 * 2 + 1];
}
return new String(cs);
}
/**
* 校验密码是否正确
*/
public static boolean verify(String password, String md5) {
char[] cs = md5.toCharArray();
char[] cs1 = new char[32];
char[] cs2 = new char[16];
for (int i = 0; i < 48; i += 3) {
cs1[i / 3 * 2] = cs[i];
cs1[i / 3 * 2 + 1] = cs[i + 2];
cs2[i / 3] = cs[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");
byte[] bs = md5.digest(src.getBytes());
return new String(new Hex().encode(bs));
} catch (Exception e) {
return null;
}
}
public static void main(String[] args) {
String password = generate("admin");
System.out.println(verify("admin", password));
}
}