我一直在研究Java String加密技术,遗憾的是我还没有找到任何关于如何在Java中使用SHA-512散列String的好教程。我读了一些关于MD5和Base64的博客,但它们并不像我想的那样安全(实际上,Base64不是加密技术),所以我更喜欢SHA-512。
答案 0 :(得分:57)
你可以将它用于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;
}
答案 1 :(得分:24)
请停止使用哈希函数对密码进行编码!它们无法提供您所需的保护。相反,您应该使用像PBKDF2,bcrypt或scrypt这样的算法。
参考文献:
答案 2 :(得分:3)
使用Apache Commons Crypt,它具有基于SHA-512的crypt()函数,可生成与libc的crypt兼容的salted哈希,因此也可用于PHP / Perl / Python / C和大多数数据库。
答案 3 :(得分:3)
使用Guava:
Hashing.sha512().hashString(s, StandardCharsets.UTF_8).toString()
答案 4 :(得分:1)
如果您愿意,可以使用它来在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;
}
答案 5 :(得分:0)
selectionSort(myarray, sortByNumber);
selectionSort(myarray, sortByLetter);
不推荐使用散列函数作为密码,但是更新的算法如bcrypt或scrypt存在
答案 6 :(得分:-1)
以下是Java MessageDigest提供的standard hashing algorithms:
您可能需要验证要提供给工厂方法的名称。
答案 7 :(得分:-1)
使用安全散列将3个盐组件(每个150个随机字符)组合到单个用户salt(用户数据库表中的用户salt,数据库表中的常规盐(使用cron作业每月更改)并隐藏一些盐应用程序库)。将安全散列的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<lenght-1; i++){
Random r = new Random();
char letter = total.charAt(r.nextInt(total.length()));
letters[i] = letter;
}
response = Arrays.toString(letters).replaceAll("\\s+","");
response = response.replaceAll(",","");
return response;
}
private static String getHash(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){
System.out.println(e);
}
return generatedPassword;
}
public static String getSecureHash(String password, String salt){
String hash = getHash(password, salt);
for (int i=0; i<20000; i++){
hash = getHash(password, hash);
}
return hash;
}
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
String salt = generateSalt(150);
String salt2 = generateSalt(150);
String salt3 = generateSalt(150);
String someString = "This is some string!";
String hash = getSecureHash(someString, salt + salt2 + salt3);
System.out.println(hash);
}