赞
踩
常见的加密算法,如MD5,此类算法为单向的,无法通过逆向破解,但由于技术的不断进步,可以通过字典和暴力破解。后来人们通过加盐来增加密码的安全性,但彩虹表的出现让这种方式也变得不安全。以至于出现了现在的PBKDF2算法。
PBKDF2算法通过多次hash来对密码进行加密。原理是通过password和salt进行hash,然后将结果作为salt在与password进行hash,多次重复此过程,生成最终的密文。此过程可能达到上千次,逆向破解的难度太大,破解一个密码的时间可能需要几百年,所以PBKDF2算法是安全的。
在web系统中最基础的一个功能就是用户密码的验证,采用pbkdf2算法对用户的密码进行加密是比较常见的作法,本篇博客将简单的给出加密的Java实现。
package com.*.*.*.utiles; import java.security.NoSuchAlgorithmException; import java.security.SecureRandom; import java.security.spec.InvalidKeySpecException; import java.security.spec.KeySpec; import javax.crypto.SecretKeyFactory; import javax.crypto.spec.PBEKeySpec; import javax.xml.bind.DatatypeConverter; public class PBKDF2 { public static final String PBKDF2_ALGORITHM = "PBKDF2WithHmacSHA1"; //盐的长度 public static final int SALT_SIZE = 16; //生成密文的长度 public static final int HASH_SIZE = 16; // 迭代次数 public static final int PBKDF2_ITERATIONS = 1000; /** * 对输入的密码进行验证 * password 密码明文 * dataPassWord 密码加密 */ public static boolean verify(String password, String dataPassWord) throws NoSuchAlgorithmException, InvalidKeySpecException { // 用相同的盐值对用户输入的密码进行加密 String result = getPBKDF2(password, dataPassWord.substring(0,16)); // 把加密后的密文和原密文进行比较,相同则验证成功,否则失败 return result.equals(dataPassWord.substring(16,dataPassWord.length())); } /** * 根据password和salt生成密文 * */ public static String getPBKDF2(String password, String salt) throws NoSuchAlgorithmException, InvalidKeySpecException { //将16进制字符串形式的salt转换成byte数组 byte[] bytes = DatatypeConverter.parseHexBinary(salt); KeySpec spec = new PBEKeySpec(password.toCharArray(), bytes, PBKDF2_ITERATIONS, HASH_SIZE * 4); SecretKeyFactory secretKeyFactory = SecretKeyFactory.getInstance(PBKDF2_ALGORITHM); byte[] hash = secretKeyFactory.generateSecret(spec).getEncoded(); //将byte数组转换为16进制的字符串 return DatatypeConverter.printHexBinary(hash); } /** * 生成随机盐值 * */ public static String getSalt() throws NoSuchAlgorithmException { SecureRandom random = SecureRandom.getInstance("SHA1PRNG"); byte[] bytes = new byte[SALT_SIZE / 2]; random.nextBytes(bytes); //将byte数组转换为16进制的字符串 String salt = DatatypeConverter.printHexBinary(bytes); return salt; } public static void main(String[] args) { try { String salt= getSalt(); System.out.println("salt:"+salt);//获取salt String miwen = getPBKDF2("111", salt); //明文密码加密 System.out.println("miwen:"+miwen); System.out.println(salt+miwen); System.out.println(verify("111", salt+miwen));//解密 } catch (Exception e) { e.printStackTrace(); } } }
赞
踩
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。