概述
訊息摘要演算法又稱為散列演算法,其核心在于散列函式的單向性,即通過散列函式可獲得對應的散列值,但不可通過該散列值反推其原始資訊,這是訊息摘要演算法的安全性的根本所在,訊息摘要演算法主要分為三大類:MD(MessageDigest,訊息摘要演算法)、SHA(Secure HashAlgorithm,安全散列演算法)和MAC(MessageAuthentication Code,訊息認證碼演算法),MD5、SHA和HMAC分別是三大類訊息摘要演算法中的代表,
MD5和SHA
1.MD5演算法是典型的訊息摘要演算法,其前身有MD2、MD3和MD4演算法,它由MD4、MD3、MD2演算法改進而來,1996年后該演算法被證實存在弱點,可以被加以破解,對于需要高度安全性的資料,專家一般建議改用其他演算法,如SHA,
2.SHA家族的五個演算法,分別是SHA-1、SHA-224、SHA-256、SHA-384,和SHA-512,SHA與MD演算法不同之處主要在于摘要長度,SHA演算法的摘要長度更長,安全性更高,
MD5和SHA在實作代碼上大部分是一致的,只是指定的演算法不一樣,
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
public class MdaUtil {
/**
* MD5/SHA訊息摘要
* @param content 資料
* @param algorithm 訊息摘要演算法
* @return
* @throws NoSuchAlgorithmException
*/
public static String messageDigestAlgorithm(String content, String algorithm) throws NoSuchAlgorithmException {
MessageDigest messageDigest = MessageDigest.getInstance(algorithm);
byte[] result = messageDigest.digest(content.getBytes());
StringBuilder sb = new StringBuilder();
for(byte b : result){
//轉16進制
String a = Integer.toHexString(b & 0xff);
//長度為1時在最高位補0
if(a.length() == 1){
a = "0" + a;
}
sb.append(a);
}
return sb.toString();
}
public static void main(String[] args) throws NoSuchAlgorithmException {
System.out.println(messageDigestAlgorithm("訊息摘要演算法", "md5"));//b7c58f860f1add7de092b1f2931a3eb9
System.out.println(messageDigestAlgorithm("訊息摘要演算法", "sha"));//ff0e2136bc6df62bbe0d9b6ad9d028852312aad5
}
}
HMAC
HMAC演算法結合了MD5和SHA演算法的優勢,并加入密鑰的支持,是一種更為安全的訊息摘要演算法,
import javax.crypto.KeyGenerator;
import javax.crypto.Mac;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.util.Base64;
public class HmacUtil {
/**
* 生成base64編碼后的密鑰
* @param algorithm 摘要演算法
* @return
* @throws Exception
*/
public static String generateKey(String algorithm) throws Exception {
KeyGenerator keyGenerator = KeyGenerator.getInstance(algorithm);
SecretKey secretKey = keyGenerator.generateKey();
return Base64.getEncoder().encodeToString(secretKey.getEncoded());
}
/**
* HMAC訊息摘要
* @param algorithm 摘要演算法
* @param key 密鑰
* @param data 資料
* @return
* @throws Exception
*/
public static String hmac(String algorithm, String key, String data) throws Exception {
SecretKey secretKey = new SecretKeySpec(Base64.getDecoder().decode(key), algorithm);
Mac mac = Mac.getInstance(algorithm);
mac.init(secretKey);
return Base64.getEncoder().encodeToString(mac.doFinal(data.getBytes()));
}
public static void main(String[] args) throws Exception {
String algorithm = "HmacMD5";
String data = "https://www.cnblogs.com/seve/p/訊息摘要演算法";
String key = generateKey(algorithm);
System.out.println("Base64編碼后的密鑰:" + key);
System.out.println("Base64編碼后的HMAC訊息摘要:" + hmac(algorithm, key, data));
}
}
檔案完整性驗證
以tomcat為例,在官網上可以看到tomcat安裝包以及它對應的經過訊息摘要演算法處理的后的值:


下載檔案,通過計算檔案的訊息摘要值來驗證檔案的完整性,如果檔案是完整的則計算出來的值和官網上的值是相同的,
import java.io.FileInputStream;
import java.io.InputStream;
import java.security.DigestInputStream;
import java.security.MessageDigest;
public class FileVerificationUtil {
/**
* 檔案訊息摘要驗證
*
* @param digestData 原摘要資料
* @param algorithm 摘要演算法
* @param inputStream 待驗證檔案
* @return
* @throws Exception
*/
public static boolean fileVerification(String digestData, String algorithm, InputStream inputStream) throws Exception {
DigestInputStream digestInputStream = new DigestInputStream(inputStream, MessageDigest.getInstance(algorithm));
int bufferSize = 1024;
byte[] buffer = new byte[bufferSize];
int read = digestInputStream.read(buffer, 0, bufferSize);
while (read > -1) {
read = digestInputStream.read(buffer, 0, bufferSize);
}
digestInputStream.close();
MessageDigest messageDigest = digestInputStream.getMessageDigest();
byte[] result = messageDigest.digest();
StringBuilder sb = new StringBuilder();
for (byte b : result) {
//轉16進制
String a = Integer.toHexString(b & 0xff);
//長度為1時在最高位補0
if (a.length() == 1) {
a = "0" + a;
}
sb.append(a);
}
return sb.toString().equals(digestData);
}
public static void main(String[] args) throws Exception {
String digestData = "https://www.cnblogs.com/seve/p/8ee33ad87e40659e501517d8ac9915ee0b19ee0fa590feb80c85f0d93c6dfe2658cdc73d2a2545ace52b7896e8a96ba6a025dda8254d6c5d9cea563c1f9e4d77";
String algorithm = "sha-512";
System.out.println(fileVerification(digestData, algorithm, new FileInputStream("F:\\chrome_download\\apache-tomcat-10.0.0-M9-windows-x64.zip")));//true
}
}
參考:Java加密與解密的藝術
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/220008.html
標籤:Java
上一篇:JavaWeb自學路線
下一篇:Java 設定Excel頁面背景
