密码加盐对密码进行保护

一般对密码都不会是明文存储,而是对密码进行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));
	}
}

这样我们的密码又多了一重保护

你可能感兴趣的:(密码加盐)