一般对密码都不会是明文存储,而是对密码进行MD5处理,增强反向解密难度。但这样还是能可以找出破绽。
如果用户可以查看数据库,那么他可以观察到自己的密码和别人的密码加密后的结果都是一样,那么,就会知道别人用的和自己就是同一个密码。
目前最流行的就是对密码进行加盐,下面用实际代码说说
package com.tenghu.core.test;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.spec.KeySpec;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.PBEKeySpec;
/**
* 安全密码工具
* @author Arvin
*
*/
public class ToolSecurityPwd {
private ToolSecurityPwd(){}
private static MessageDigest md=null;
static{
try {
md=MessageDigest.getInstance("SHA-1");
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
}
/**
* 判断密码是否是正确的
* @param password 需要验证的秘密
* @param encryptedPassword 加密后的密码
* @param salt 密码盐
* @return
*/
public static boolean authenticate(String password,String encryptedPassword,String salt){
//尝试输入密码加密
String encryptedAttemptedPassword=getEncryptedPassword(password, salt);
//判断密码是否相等
return encryptedPassword.equals(encryptedAttemptedPassword);
}
/**
* 获取加密后的密码
* @param password 明文密码
* @param salt 密码盐
* @return
*/
public static String getEncryptedPassword(String password,String salt){
String algorithm="PBKDF2WithHmacSHA1";//运算法则
int derivedKeyLength=160;//生成密码长度
int iterations=20000;//迭代次数
KeySpec spec=new PBEKeySpec(password.toCharArray(), salt.getBytes(), iterations,derivedKeyLength);
try {
SecretKeyFactory skf=SecretKeyFactory.getInstance(algorithm);
return byteToStr(skf.generateSecret(spec).getEncoded()).toLowerCase();
} catch (Exception e) {
e.printStackTrace();
}
return "";
}
/**
* 生成密码盐字符串
* @return
*/
public static String generateSalt(){
SecureRandom random=new SecureRandom();
byte[] salt=new byte[8];
random.nextBytes(salt);
return byteToStr(md.digest(salt)).toLowerCase();
}
/**
* 将二进制数组转为字符串
* @param bytes
* @return
*/
private static String byteToStr(byte[] bytes){
String tempStr="";
for(int i=0;i<bytes.length;i++){
tempStr+=byteToHexStr(bytes[i]);
}
return tempStr;
}
/**
* 将字节转为十六进制字符串
* @param mybyte
* @return
*/
private static String byteToHexStr(byte mybyte){
char[] digit={'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
char[] tempArr=new char[2];
tempArr[0]=digit[(mybyte>>>4)&0X0F];
tempArr[1]=digit[mybyte&0X0F];
return new String(tempArr);
}
public static void main(String[] args) {
//获取密码盐
String salt=generateSalt();
//获取加密后的密文
String encryptedPassword=getEncryptedPassword("zhangsan", salt);
System.out.println(authenticate("zhangsan1", encryptedPassword, salt));
}
}
这样我们的密码又多了一重保护