WeChat search: Code Farm StayUp
Homepage address: https://gozhuyinglong.github.io
Source code sharing: https://github.com/gozhuyinglong/blog-demos
1. Definition
One-way hash function (one-way hash function) refers to the calculation of different input values through a one-way hash function to obtain a fixed-length output value. This input value is called message (message), and the output value is called hash value (hash value).
The one-way hash function is also called message digest function (message digest function), hash function or hash function . The input message is also called (pre-image). The output hash value is also called message digest (message digest) or fingerprint (fingerprint), which is equivalent to the ID of the message.
There are many implementation algorithms for one-way hash functions, the common ones are: MD5 , SHA-1 , SHA-2 and SHA-3 .
2. Features
Through the above definition, our understanding of the one-way hash function is still vague. The following describes the characteristics of the one-way hash function to deepen the impression.
2.1 The length of the hash value is fixed
Regardless of the length of the message, the length of the hash value calculated using the same algorithm is always fixed. For example, MD5 algorithm, no matter how much input, the length of the generated hash value is always 128 bits (16 bytes).
However, a bit is a unit that a computer can recognize, and we humans are more accustomed to using a hexadecimal string to represent it (a byte occupies two hexadecimal characters).
2.2 Different messages have different hash values
Using the same message, the generated hash value must be the same.
Use different messages, the hash value generated is not the same. Even if there is only one bit difference, the obtained hash value will be very different.
This feature is also called collision resistance , for algorithms with weak collision resistance, we should not use it.
2.3 Have unidirectionality
The hash value can only be calculated from the message, and the message cannot be inversely calculated from the hash value.
2.4 Fast calculation speed
The calculation of the hash value is fast. Although the longer the message, the longer it takes to calculate the hash value, but it will also be completed in a short time.
3. Common Algorithms
The MD5 and SHA-1 algorithms have been compromised and should not be used for new purposes; SHA-2 and SHA-3 are still safe and can be used.
SHA-2 includes: SHA-224, SHA-256, SHA-384, SHA-512, SHA-512/224, SHA-512/256.
SHA-3 includes: SHA3-224, SHA3-256, SHA3-384, SHA3-512.
Algorithm name | Hash length | Is it safe |
---|---|---|
MD5 | 128 | Not safe |
SHA-1 | 160 | Not safe |
SHA-224 | 224 | Safety |
SHA-256 | 256 | Safety |
SHA-384 | 384 | Safety |
SHA-512 | 512 | Safety |
SHA-512/224 | 224 | Safety |
SHA-512/256 | 256 | Safety |
SHA3-224 | 224 | Safety |
SHA3-256 | 256 | Safety |
SHA3-384 | 384 | Safety |
SHA3-512 | 512 | Safety |
4. Application Scenario
One-way hash function does not ensure the confidentiality of information, it is a cryptographic technique to ensure the integrity of information. Let's look at its application scenarios.
4.1 User password protection
When the user sets the password, the password itself is not recorded, only the hash value of the password is recorded, and only the user knows the plaintext of the password. When verifying the password, as long as the entered password is correct, the hash value obtained must be the same, indicating that the verification is correct.
In order to prevent the rainbow table from cracking, the password can also be salted. As long as the password is verified, the same salt can be used to complete the verification.
The advantage of using the hash value to store the password is that even if the database is stolen, the ciphertext cannot be deduced from what the plaintext is, which makes the password storage more secure.
4.2 Interface verification
In order to ensure the security of the interface, it can be sent by signing.
The sender and receiver must have a shared secret key . When the sender sends a request to the receiver, a signature is attached to the parameters (the signature is generated by the shared secret key + service parameter , which is encrypted by a one-way hash function). After the receiver receives it, it uses the same method to generate a signature, and then compares it with the received signature. If it is consistent, the signature verification is successful.
In this way, it is possible to verify whether the service parameters have been tampered with, and to verify the identity of the sender.
4.3 File integrity check
When a file is mounted on a website, its hash value and algorithm are also attached, such as the official Tomcat website.
After downloading, the user calculates its hash value and compares whether the result is the same, thereby verifying the integrity of the file.
4.4 Cloud Disk Second Transmission
When we put our favorite video on the network disk, we found that it only took a few seconds to upload successfully, and this file is a few gigabytes in size, how do we do it?
In fact, this "second transmission" function can be implemented using a one-way hash function.
When we upload a file, the cloud disk client will first generate a hash value for the file. Use this hash value to match in the database. If it matches, it means that the file already exists on the cloud server. Only by associating the hash value with the user, this "upload" can be completed.
In this way, only one copy of a file is stored on the cloud server, which greatly saves the space of the cloud server.
5. Code Implementation
The java.security.MessageDigest
class of JDK provides us with a message digest algorithm for MD5 and SHA hash value generation. The following code is simply encapsulated for direct use.
public class MDUtil {
/**
* MD5 加密
*
* @param data 要加密的数据
* @return 32位十六进制字符串
*/
public static String MD5(byte[] data) {
try {
MessageDigest md = MessageDigest.getInstance("MD5");
byte[] bytes = md.digest(data);
return bytesToHexString(bytes);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
return "";
}
/**
* MD5 加密
*
* @param data 要加密的数据
* @return 32位十六进制字符串
*/
public static String MD5(String data) {
return MD5(data.getBytes());
}
/**
* SHA-1 加密
*
* @param data 要加密的数据
* @return 40位十六进制字符串
*/
public static String SHA1(byte[] data) {
try {
MessageDigest md = MessageDigest.getInstance("SHA-1");
byte[] bytes = md.digest(data);
return bytesToHexString(bytes);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
return "";
}
/**
* SHA-1 加密
*
* @param data 要加密的数据
* @return 40位十六进制字符串
*/
public static String SHA1(String data) {
return SHA1(data.getBytes());
}
/**
* SHA-224 加密
*
* @param data 要加密的数据
* @return 56位十六进制字符串
*/
public static String SHA224(byte[] data) {
try {
MessageDigest md = MessageDigest.getInstance("SHA-224");
byte[] bytes = md.digest(data);
return bytesToHexString(bytes);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
return "";
}
/**
* SHA-224 加密
*
* @param data 要加密的数据
* @return 56位十六进制字符串
*/
public static String SHA224(String data) {
return SHA224(data.getBytes());
}
/**
* SHA-256 加密
*
* @param data 要加密的数据
* @return 64位十六进制字符串
*/
public static String SHA256(byte[] data) {
try {
MessageDigest md = MessageDigest.getInstance("SHA-256");
byte[] bytes = md.digest(data);
return bytesToHexString(bytes);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
return "";
}
/**
* SHA-256 加密
*
* @param data 要加密的数据
* @return 64位十六进制字符串
*/
public static String SHA256(String data) {
return SHA256(data.getBytes());
}
/**
* SHA-384 加密
*
* @param data 要加密的数据
* @return 96位十六进制字符串
*/
public static String SHA384(byte[] data) {
try {
MessageDigest md = MessageDigest.getInstance("SHA-384");
byte[] bytes = md.digest(data);
return bytesToHexString(bytes);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
return "";
}
/**
* SHA-384 加密
*
* @param data 要加密的数据
* @return 96位十六进制字符串
*/
public static String SHA384(String data) {
return SHA384(data.getBytes());
}
/**
* SHA-512 加密
*
* @param data 要加密的数据
* @return 128位十六进制字符串
*/
public static String SHA512(byte[] data) {
try {
MessageDigest md = MessageDigest.getInstance("SHA-512");
byte[] bytes = md.digest(data);
return bytesToHexString(bytes);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
return "";
}
/**
* SHA-512 加密
*
* @param data 要加密的数据
* @return 128位十六进制字符串
*/
public static String SHA512(String data) {
return SHA512(data.getBytes());
}
/**
* 将字节数组转换为十六进制字符串
*
* @param bytes 字节数组
* @return 十六进制字符串
*/
private static String bytesToHexString(byte[] bytes) {
StringBuilder hexValue = new StringBuilder();
for (byte b : bytes) {
int val = b & 0xFF;
if (val < 16) {
hexValue.append("0");
}
hexValue.append(Integer.toHexString(val));
}
return hexValue.toString();
}
}
The following uses these algorithms to calculate the hash value of "123456":
public static void main(String[] args) {
System.out.println("MD5\t\t" + MDUtil.MD5("123456"));
System.out.println("SHA-1\t" + MDUtil.SHA1("123456"));
System.out.println("SHA-224\t" + MDUtil.SHA224("123456"));
System.out.println("SHA-256\t" + MDUtil.SHA256("123456"));
System.out.println("SHA-384\t" + MDUtil.SHA384("123456"));
System.out.println("SHA-512\t" + MDUtil.SHA512("123456"));
}
Output result:
MD5 e10adc3949ba59abbe56e057f20f883e
SHA-1 7c4a8d09ca3762af61e59520943dc26494f8941b
SHA-224 f8cdb04495ded47615258f9dc6a3f4707fd2405434fefc3cbf4ef4e6
SHA-256 8d969eef6ecad3c29a3a629280e686cf0c3f5d5a86aff3ca12020c923adc6c92
SHA-384 0a989ebc4a77b56a6e2bb7b19d995d185ce44090c13e2984b7ecc6d446d4b61ea9991b76a4c2f04b1b4d244841449454
SHA-512 ba3253876aed6bc22d4a6ff53d8406c6ad864195ed144ab5c87621b6c233b548baeae6956df346ec8c17f5ea10f35ee3cbc514797ed7ddd3145464e2a0bab413
I use Java8, which does not support SHA-3, so the above code only encapsulates MD5, SHA-1 and SHA-2.
SHA-3 is supported since Java9
6. Complete code
For the complete code, please visit my Github, if it is helpful to you, welcome to Star, thank you!
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。