[英]How to hash a password with SHA-512 in Java?
I've been investigating a bit about Java String encryption techniques and unfortunately I haven't find any good tutorial how to hash String with SHA-512 in Java; 我一直在研究Java String加密技术,遗憾的是我还没有找到任何关于如何在Java中使用SHA-512散列String的好教程。 I read a few blogs about MD5 and Base64, but they are not as secure as I'd like to (actually, Base64 is not an encryption technique), so I prefer SHA-512.
我读了一些关于MD5和Base64的博客,但它们并不像我想的那样安全(实际上,Base64不是加密技术),所以我更喜欢SHA-512。
you can use this for 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;
}
Please stop using hash functions to encode passwords! 请停止使用哈希函数对密码进行编码! They do not provide the protection you need.
它们无法提供您所需的保护。 Instead, you should be using an algorithm like PBKDF2, bcrypt, or scrypt.
相反,您应该使用像PBKDF2,bcrypt或scrypt这样的算法。
References: 参考文献:
使用番石榴 :
Hashing.sha512().hashString(s, StandardCharsets.UTF_8).toString()
Use Apache Commons Crypt, it features SHA-512 based crypt() functions that generate salted hashes that are even compatible to libc's crypt and thus usable in PHP/Perl/Python/C and most databases, too. 使用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 https://commons.apache.org/proper/commons-codec/apidocs/org/apache/commons/codec/digest/Crypt.html#Crypt%28%29
you could use this to hash a password in java if you want to. 如果你愿意,可以使用它来在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;
}
It's not recommended to use hash functions for passwords though, newer alogrithms like bcrypt, or scrypt exist 不推荐使用密码的哈希函数,比如bcrypt或scrypt这样的新算法
With secure hashing combine 3 salt components (of 150 random characters each) to a individual user salt (user salt from the user database table, general salt in a database table (monthly change with cron job) and hide some salt in the application library). 使用安全散列将3个盐组件(每个150个随机字符)组合到单个用户salt(用户数据库表中的用户salt,数据库表中的常规盐(使用cron作业每月更改)并在应用程序库中隐藏一些salt) 。 Align the for loop amount of the secure hash to your needs.
将安全散列的for循环量与您的需求对齐。 See answer above for hashing method.
有关散列方法,请参阅上面的答案。
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);
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.