java常用加密演算法之pbkdf2
阿新 • • 發佈:2019-02-08
PBKDF2簡介
常見的加密演算法,如MD5,此類演算法為單向的,無法通過逆向破解,但由於技術的不斷進步,可以通過字典和暴力破解。後來人們通過加鹽來增加密碼的安全性,但彩虹表的出現讓這種方式也變得不安全。以至於出現了現在的PBKDF2演算法。
PBKDF2演算法通過多次hash來對密碼進行加密。原理是通過password和salt進行hash,然後將結果作為salt在與password進行hash,多次重複此過程,生成最終的密文。此過程可能達到上千次,逆向破解的難度太大,破解一個密碼的時間可能需要幾百年,所以PBKDF2演算法是安全的。
在web系統中最基礎的一個功能就是使用者密碼的驗證,採用pbkdf2演算法對使用者的密碼進行加密是比較常見的作法,本篇部落格將簡單的給出加密的Java實現。
演算法的Java實現
public class PBKDF2 { public static final String PBKDF2_ALGORITHM = "PBKDF2WithHmacSHA1"; //鹽的長度 public static final int SALT_SIZE = 16; //生成密文的長度 public static final int HASH_SIZE = 32; // 迭代次數 public static final int PBKDF2_ITERATIONS = 1000; /** * 對輸入的密碼進行驗證 * */ public static boolean verify(String password, String salt, String key) throws NoSuchAlgorithmException, InvalidKeySpecException { // 用相同的鹽值對使用者輸入的密碼進行加密 String result = getPBKDF2(password, salt); // 把加密後的密文和原密文進行比較,相同則驗證成功,否則失敗 return result.equals(key); } /** * 根據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; } }