消息摘要
消息摘要(Message Digest)又稱爲數字摘要(Digital Digest)
它是一個唯一對應一個消息或文本的固定長度的值,它由一個單向Hash加密函數對消息進行作用而產生
使用數字摘要生成的值是不可以篡改的,爲了保證文件或者值的安全
特點
無論輸入的消息有多長,計算出來的消息摘要的長度總是固定的。例如應用MD5算法摘要的消息有128個比特位,用SHA-1算法摘要的消息最終有160比特位的輸出
只要輸入的消息不同,對其進行摘要以後產生的摘要消息也必不相同;但相同的輸入必會產生相同的輸出
消息摘要是單向、不可逆的
常見算法
- MD5
- SHA1
- SHA256
- SHA512
獲取字符串消息摘要
package com.atguigu.digest;
import javax.sound.midi.Soundbank;
import java.security.MessageDigest;
/**
* DigestDemo1
*
* @Author: 尚硅谷
* @CreateTime: 2020-03-17
* @Description:
*/
public class DigestDemo1 {
public static void main(String[] args) throws Exception{
// 原文
String input = "aa";
// 算法
String algorithm = "MD5";
// 獲取數字摘要對象
MessageDigest messageDigest = MessageDigest.getInstance(algorithm);
// 獲取消息數字摘要的字節數組
byte[] digest = messageDigest.digest(input.getBytes());
// base64編碼
System.out.println(Base64.encode(digest));
}
}
數字摘要轉換成 16 進制
// 4124bc0a9335c27f086f24ba207a4912 md5 在線校驗
// QSS8CpM1wn8IbyS6IHpJEg== 消息摘要使用的是16進制
數字摘要算法
package com.atguigu.digest;
import com.sun.org.apache.xml.internal.security.utils.Base64;
import javax.sound.midi.Soundbank;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
/**
* DigestDemo1
*
* @Author: 尚硅谷
* @CreateTime: 2020-03-17
* @Description:
*/
public class DigestDemo1 {
public static void main(String[] args) throws Exception{
// 4124bc0a9335c27f086f24ba207a4912 md5 在線校驗
// QSS8CpM1wn8IbyS6IHpJEg== 消息摘要使用的是16進制
// 原文
String input = "aa";
// 算法
String algorithm = "MD5";
// 獲取數字摘要對象
String md5 = getDigest(input, "MD5");
System.out.println(md5);
String sha1 = getDigest(input, "SHA-1");
System.out.println(sha1);
String sha256 = getDigest(input, "SHA-256");
System.out.println(sha256);
String sha512 = getDigest(input, "SHA-512");
System.out.println(sha512);
}
private static String toHex(byte[] digest) throws Exception {
// System.out.println(new String(digest));
// base64編碼
// System.out.println(Base64.encode(digest));
// 創建對象用來拼接
StringBuilder sb = new StringBuilder();
for (byte b : digest) {
// 轉成 16進制
String s = Integer.toHexString(b & 0xff);
if (s.length() == 1){
// 如果生成的字符只有一個,前面補0
s = "0"+s;
}
sb.append(s);
}
System.out.println("16進制數據的長度:" + sb.toString().getBytes().length);
return sb.toString();
}
private static String getDigest(String input, String algorithm) throws Exception {
MessageDigest messageDigest = MessageDigest.getInstance(algorithm);
// 消息數字摘要
byte[] digest = messageDigest.digest(input.getBytes());
System.out.println("密文的字節長度:" + digest.length);
return toHex(digest);
}
}
獲取文件的數字摘要
public class DigestDemo {
public static void main(String[] args) throws Exception{
String input = "aa";
String algorithm = "MD5";
// sha1 可以實現秒傳功能
String sha1 = getDigestFile("apache-tomcat-9.0.10-windows-x64.zip", "SHA-1");
System.out.println(sha1);
String sha512 = getDigestFile("apache-tomcat-9.0.10-windows-x64.zip", "SHA-512");
System.out.println(sha512);
String md5 = getDigest("aa", "MD5");
System.out.println(md5);
String md51 = getDigest("aa ", "MD5");
System.out.println(md51);
}
private static String getDigestFile(String filePath, String algorithm) throws Exception{
FileInputStream fis = new FileInputStream(filePath);
int len;
byte[] buffer = new byte[1024];
ByteArrayOutputStream baos = new ByteArrayOutputStream();
while ( (len = fis.read(buffer))!=-1){
baos.write(buffer,0,len);
}
// 獲取消息摘要對象
MessageDigest messageDigest = MessageDigest.getInstance(algorithm);
// 獲取消息摘要
byte[] digest = messageDigest.digest(baos.toByteArray());
System.out.println("密文的字節長度:"+digest.length);
return toHex(digest);
}
private static String getDigest(String input, String algorithm) throws Exception{
MessageDigest messageDigest = MessageDigest.getInstance(algorithm);
byte[] digest = messageDigest.digest(input.getBytes());
System.out.println("密文的字節長度:"+digest.length);
return toHex(digest);
}
private static String toHex(byte[] digest) {
// System.out.println(new String(digest));
// 消息摘要進行表示的時候,是用16進制進行表示
StringBuilder sb = new StringBuilder();
for (byte b : digest) {
// 轉成16進制
String s = Integer.toHexString(b & 0xff);
// 保持數據的完整性,前面不夠的用0補齊
if (s.length()==1){
s="0"+s;
}
sb.append(s);
}
System.out.println("16進制數據的長度:"+ sb.toString().getBytes().length);
return sb.toString();
}
}
總結
MD5算法 : 摘要結果16個字節, 轉16進制後32個字節
SHA1算法 : 摘要結果20個字節, 轉16進制後40個字節
SHA256算法 : 摘要結果32個字節, 轉16進制後64個字節
SHA512算法 : 摘要結果64個字節, 轉16進制後128個字節