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