如何在Java中使用SHA-512散列密码?

我一直在研究Java String加密技术,遗憾的是我还没有找到任何关于如何在Java中使用SHA-512散列String的好教程。 我读了一些关于MD5和Base64的博客,但它们并不像我想的那样安全(实际上,Base64不是加密技术),所以我更喜欢SHA-512。

您可以将它用于SHA-512

import java.nio.charset.StandardCharsets; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; public String get_SHA_512_SecurePassword(String passwordToHash, String salt){ String generatedPassword = null; try { MessageDigest md = MessageDigest.getInstance("SHA-512"); md.update(salt.getBytes(StandardCharsets.UTF_8)); byte[] bytes = md.digest(passwordToHash.getBytes(StandardCharsets.UTF_8)); StringBuilder sb = new StringBuilder(); for(int i=0; i< bytes.length ;i++){ sb.append(Integer.toString((bytes[i] & 0xff) + 0x100, 16).substring(1)); } generatedPassword = sb.toString(); } catch (NoSuchAlgorithmException e){ e.printStackTrace(); } return generatedPassword; } 

使用Apache Commons Crypt,它具有基于SHA-512的crypt()函数,可生成与libc的crypt兼容的salted哈希,因此也可用于PHP / Perl / Python / C和大多数数据库。

https://commons.apache.org/proper/commons-codec/apidocs/org/apache/commons/codec/digest/Crypt.html#Crypt%28%29

如果你愿意,可以使用它来在java中哈希密码。

 public static boolean isHashMatch(String password, // the password you want to check. String saltedHash, // the salted hash you want to check your password against. String hashAlgorithm, // the algorithm you want to use. String delimiter) throws NoSuchAlgorithmException // the delimiter that has been used to delimit the salt and the hash. { // get the salt from the salted hash and decode it into a byte[]. byte[] salt = Base64.getDecoder() .decode(saltedHash.split(delimiter)[0]); // compute a new salted hash based on the provided password and salt. String pw_saltedHash = computeSaltedBase64Hash(password, salt, hashAlgorithm, delimiter); // check if the provided salted hash matches the salted hash we computed from the password and salt. return saltedHash.equals(pw_saltedHash); } public static String computeSaltedBase64Hash(String password, // the password you want to hash String hashAlgorithm, // the algorithm you want to use. String delimiter) throws NoSuchAlgorithmException // the delimiter that will be used to delimit the salt and the hash. { // compute the salted hash with a random salt. return computeSaltedBase64Hash(password, null, hashAlgorithm, delimiter); } public static String computeSaltedBase64Hash(String password, // the password you want to hash byte[] salt, // the salt you want to use (uses random salt if null). String hashAlgorithm, // the algorithm you want to use. String delimiter) throws NoSuchAlgorithmException // the delimiter that will be used to delimit the salt and the hash. { // transform the password string into a byte[]. we have to do this to work with it later. byte[] passwordBytes = password.getBytes(); byte[] saltBytes; if(salt != null) { saltBytes = salt; } else { // if null has been provided as salt parameter create a new random salt. saltBytes = new byte[64]; SecureRandom secureRandom = new SecureRandom(); secureRandom.nextBytes(saltBytes); } // MessageDigest converts our password and salt into a hash. MessageDigest messageDigest = MessageDigest.getInstance(hashAlgorithm); // concatenate the salt byte[] and the password byte[]. byte[] saltAndPassword = concatArrays(saltBytes, passwordBytes); // create the hash from our concatenated byte[]. byte[] saltedHash = messageDigest.digest(saltAndPassword); // get java's base64 encoder for encoding. Encoder base64Encoder = Base64.getEncoder(); // create a StringBuilder to build the result. StringBuilder result = new StringBuilder(); result.append(base64Encoder.encodeToString(saltBytes)) // base64-encode the salt and append it. .append(delimiter) // append the delimiter (watch out! don't use regex expressions as delimiter if you plan to use String.split() to isolate the salt!) .append(base64Encoder.encodeToString(saltedHash)); // base64-encode the salted hash and append it. // return a salt and salted hash combo. return result.toString(); } public static byte[] concatArrays(byte[]... arrays) { int concatLength = 0; // get the actual length of all arrays and add it so we know how long our concatenated array has to be. for(int i = 0; i< arrays.length; i++) { concatLength = concatLength + arrays[i].length; } // prepare our concatenated array which we're going to return later. byte[] concatArray = new byte[concatLength]; // this index tells us where we write into our array. int index = 0; // concatenate the arrays. for(int i = 0; i < arrays.length; i++) { for(int j = 0; j < arrays[i].length; j++) { concatArray[index] = arrays[i][j]; index++; } } // return the concatenated arrays. return concatArray; } 
 import java.nio.charset.StandardCharsets; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import org.apache.commons.codec.binary.Hex; public String getHashSHA512(String StringToHash, String salt){ String generatedPassword = null; try { MessageDigest md = MessageDigest.getInstance("SHA-512"); md.update(salt.getBytes(StandardCharsets.UTF_8)); byte[] bytes = md.digest(StringToHash.getBytes(StandardCharsets.UTF_8)); generatedPassword = Hex.encodeHexString(bytes); } catch (NoSuchAlgorithmException e){ e.printStackTrace(); } return generatedPassword; } 

不建议对密码使用哈希函数,但是更新的算法如bcrypt或scrypt存在

使用番石榴 :

 Hashing.sha512().hashString(s, StandardCharsets.UTF_8).toString() 

以下是Java MessageDigest提供的标准哈希算法 :

  1. MD2
  2. MD5
  3. SHA-1
  4. SHA-256
  5. SHA-384
  6. SHA-512

您可能需要validation要提供给工厂方法的名称。

使用安全散列将3个盐组件(每个150个随机字符)组合到单个用户salt(用户数据库表中的用户salt,数据库表中的常规盐(使用cron作业每月更改)并在应用程序库中隐藏一些salt) 。 将安全散列的for循环量与您的需求对齐。 有关散列方法,请参阅上面的答案。

 private static String generateSalt(int lenght){ String abcCapitals = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; String abcLowerCase = "abcdefghijklmnopqrstuvwxyz"; String numbers = "01234567890123456789"; String characters = "!@#$%^&*!@#$%%^^&*"; String total = abcCapitals + abcLowerCase + numbers + characters; String response = ""; char letters[] = new char[lenght]; for (int i=0; i