1.生成鹽值
public static String getSalt() throws NoSuchAlgorithmException { // Use a SecureRandom generator, SHA1PRNG算法是基於SHA-1實現且保密性較強的隨機數生成器 SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG"); // Create array for salt byte[] salt = new byte[16]; // Get a random salt secureRandom.nextBytes(salt); // 將十進制數轉換成十六進制(使用&運算,正數部分沒變,負數部分二進制從右往左第9位及以上都為0 StringBuilder builder = new StringBuilder(); for (byte num : salt) { builder.append(Integer.toString((num & 0xff) + 0x100, 16).substring(1)); } return builder.toString(); }
2.最簡單的MD5(唾棄,了解一下即可)
public static String getSimpleMD5Code(String password) { try { // Create MessageDigest instance for MD5 MessageDigest md5 = MessageDigest.getInstance("MD5"); // digest(byte[] input)使用指定的byte數組對摘要進行最后更新,然后完成摘要計算,此方法首先調用 // update(input),向update方法傳遞input數組,然后調用digest()。 byte[] bytes = md5.digest(password.getBytes()); // 如有中文,須添加字符集 StringBuilder builder = new StringBuilder(); for (byte num : bytes) { builder.append(Integer.toString((num & 0xff) + 0x100, 16).substring(1)); } return builder.toString(); } catch (NoSuchAlgorithmException e) { System.out.println("algorithm wrong"); return null; } }
3.MD5+鹽值(安全要求較低可以用)
public static String getMD5WithSaltCode(String password, String salt) { try { // Create MessageDigest instance for MD5 MessageDigest md5 = MessageDigest.getInstance("MD5"); // Get password mix salt,可以做多種組合,增加原始密碼長度、復雜度 password = salt + password + salt; // digest(byte[] input)使用指定的byte數組對摘要進行最后更新,然后完成摘要計算,此方法首先調用 // update(input),向update方法傳遞input數組,然后調用digest()。 byte[] bytes = md5.digest(password.getBytes()); // 如有中文,須添加字符集 StringBuilder builder = new StringBuilder(); for (byte num : bytes) { builder.append(Integer.toString((num & 0xff) + 0x100, 16).substring(1)); } return builder.toString(); } catch (NoSuchAlgorithmException e) { System.out.println("algorithm wrong"); return null; } }
4.使用SHA家族(中級安全,比MD家族強)
public static String getSHACode(String password, String salt, String algorithm) { // algorithm加密算法可選SHA-1/SHA-256/SHA-384/SHA-512 try { MessageDigest md = MessageDigest.getInstance(algorithm); // Get password mix salt,可以做多種組合,增加原始密碼長度、復雜度 password = salt + password + salt; // digest(byte[] input)使用指定的byte數組對摘要進行最后更新,然后完成摘要計算,此方法首先調用 // update(input),向update方法傳遞input數組,然后調用digest()。 byte[] bytes = md.digest(password.getBytes()); // 如有中文,須添加字符集 StringBuilder builder = new StringBuilder(); for (byte num : bytes) { builder.append(Integer.toString((num & 0xff) + 0x100, 16).substring(1)); } return builder.toString(); } catch (NoSuchAlgorithmException e) { System.out.println("algorithm wrong"); return null; } }
5.PBKDF2,安全性較高,比上述的強
public static String getPBKDF2Code(String password, String salt) { // 迭代次數,可依情況修改 int interNum = 10000; PBEKeySpec spec = new PBEKeySpec(password.toCharArray(), salt.getBytes(), interNum, 128 * 4);//128位16進制字符 // PBKDF2算法應用很廣泛,大多數數據庫支持該算法,可用於到處密鑰,也可用於口令保存 try { // SecretKeyFactory secretKeyFactory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1"); 使用PBKDF2WithHmacSHA1 SecretKeyFactory secretKeyFactory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256"); byte[] bytes = secretKeyFactory.generateSecret(spec).getEncoded(); StringBuilder builder = new StringBuilder(); for (byte num : bytes) { builder.append(Integer.toString((num & 0xff) + 0x100, 16).substring(1)); } return builder.toString(); } catch (NoSuchAlgorithmException | InvalidKeySpecException e) { System.out.println("algorithm wrong"); return null; } }