Java安全——訊息摘要
標籤(空格分隔): Java 安全
[toc]
概念
訊息摘要(Message Digest)又稱為數字摘要(Digital Digest)。它是一個唯一對應一個訊息或文字的固定長度的值,它由一個單向Hash加密函式對訊息進行作用而產生。如果訊息在途中改變了,則接收者通過對收到訊息的新產生的摘要與原摘要比較,就可知道訊息是否被改變了。因此訊息摘要保證了訊息的完整性。 訊息摘要採用單向Hash 函式將需加密的明文”摘要”成一串128bit的密文,這一串密文亦稱為數字指紋(Finger Print),它有固定的長度,且不同的明文摘要成密文,其結果總是不同的,而同樣的明文其摘要必定一致。這樣這串摘要便可成為驗證明文是否是”真身”的”指紋”了。 <<百度百科>>
訊息摘要其實是我們日常開發中經常遇到的,比如MD5演算法就是一種摘要。它是Java安全提供者體系中最簡單的標準引擎。本文不會討論演算法本身,只關注Java語言體系中的實現和使用方法。具體演算法原理,後續撰文學習並補充。
使用
訊息摘要通過MessageDigest類實現。訊息摘要通過getInstance()方法獲取演算法例項。通過update()方法為訊息摘要增加內容位元組。根據digest()方法利用累計的內容位元組計算最後的摘要。
下面的test列出了一些細節:
import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Base64;
import org.apache.commons.codec.binary.Hex;
public class MessageDigestTest {
private static String TEST_DATA = "i am a test";
public static void main(String[] args)
throws NoSuchAlgorithmException, UnsupportedEncodingException {
MessageDigest md = MessageDigest.getInstance("SHA");
print(md);
md = MessageDigest.getInstance("MD5");
print(md);
md = MessageDigest.getInstance("MD2");
print(md);
md = MessageDigest.getInstance("SHA-256");
print(md);
md = MessageDigest.getInstance("SHA-384");
print(md);
md = MessageDigest.getInstance("SHA-224");
print(md);
md = MessageDigest.getInstance("SHA-512");
print(md);
}
private static void print(MessageDigest md) throws UnsupportedEncodingException {
System.out.println("Algorithm: " + md.getAlgorithm());
System.out.println(" Provider: " + md.getProvider());
long start = System.nanoTime();
md.update(TEST_DATA.getBytes("UTF-8"));
byte[] digest = md.digest();
long time = System.nanoTime() - start;
System.out.println(" Time cost: " + time + "ns");
System.out.println(" Byte length: " + digest.length);
String digestBase64Str = Base64.getEncoder().encodeToString(digest);
System.out.println(" Base64: " + digestBase64Str + " len: " + digestBase64Str.length());
String digestHexStr = Hex.encodeHexString(digest);
System.out.println(" Hex: " + digestHexStr + " len: " + digestHexStr.length());
}
}
輸出結果如下:
Algorithm: SHA
Provider: SUN version 1.8
Time cost: 432582ns
Byte length: 20
Base64: Bj5BsD+J+PLpYZYVDR+14WwSKlg= len: 28
Hex: 063e41b03f89f8f2e96196150d1fb5e16c122a58 len: 40
Algorithm: MD5
Provider: SUN version 1.8
Time cost: 46030ns
Byte length: 16
Base64: dCVplUXLIKBlw/aWvoOCyA== len: 24
Hex: 7425699545cb20a065c3f696be8382c8 len: 32
Algorithm: MD2
Provider: SUN version 1.8
Time cost: 80611ns
Byte length: 16
Base64: v4z32/PgSXZCrWvnOcRiaQ== len: 24
Hex: bf8cf7dbf3e0497642ad6be739c46269 len: 32
Algorithm: SHA-256
Provider: SUN version 1.8
Time cost: 205859ns
Byte length: 32
Base64: lRctjSY3GOo6erswsyheP21CNtAAGxnsUHVF17u7RYg= len: 44
Hex: 95172d8d263718ea3a7abb30b3285e3f6d4236d0001b19ec507545d7bbbb4588 len: 64
Algorithm: SHA-384
Provider: SUN version 1.8
Time cost: 258382ns
Byte length: 48
Base64: /B642f1Y+PPKgeIJHFpbEDLJwX2nqWaMaC8nVQuboRWN5MZeKpGaLiySWUEr4xB9 len: 64
Hex: fc1eb8d9fd58f8f3ca81e2091c5a5b1032c9c17da7a9668c682f27550b9ba1158de4c65e2a919a2e2c9259412be3107d len: 96
Algorithm: SHA-224
Provider: SUN version 1.8
Time cost: 76539ns
Byte length: 28
Base64: 6m2pv1G0lnWlKO4ahn7iJAQF8XMo5cHR3LBO3w== len: 40
Hex: ea6da9bf51b49675a528ee1a867ee2240405f17328e5c1d1dcb04edf len: 56
Algorithm: SHA-512
Provider: SUN version 1.8
Time cost: 143649ns
Byte length: 64
Base64: Vv6LL9QqfeCq1ClbN8JdMTcU1PzUbsRQKgmc7vVDbcHTB6i/SryXIjWcRcrfYa6n2QxstmSwUY9AME3pTmykNw== len: 88
Hex: 56fe8b2fd42a7de0aad4295b37c25d313714d4fcd46ec4502a099ceef5436dc1d307a8bf4abc9722359c45cadf61aea7d90c6cb664b0518f40304de94e6ca437 len: 128
訊息摘要實現是通過Java自己Sun的實現來做的。我們常見的是MD5和SHA演算法。
安全訊息摘要
考慮到訊息摘要的不安全性——拿到原文並知道演算法,就可以得到正確的訊息摘要。人們又加入了金鑰元素,得到了安全訊息摘要——MAC(Message Authentication Code)。MAC的特點是僅通過原文是無法計算出安全訊息摘要的。還需要一個雙方都知道的訊息金鑰。如果有人修改了訊息本體,又修改了訊息摘要,但是因為沒有使用金鑰,那麼將被發現破壞了資料。計算MAC的方法有很多,但是核心Java API沒有相關實現。Java的實現主要是通過JCE提供者來實現的。Mac類對應訊息摘要的MessageDigest類。計算訊息摘要時需要一個金鑰。金鑰的管理是另一個話題了。這裡主要講MAC的演算法,JCE實現主要基於HmacSHA1和HmacMD5。具體provider提供了哪些MAC相關的演算法,它們比較如何,見下面的程式碼:
package com.taobao.cd.security;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.Base64;
import javax.crypto.KeyGenerator;
import javax.crypto.Mac;
import javax.crypto.SecretKey;
import org.apache.commons.codec.binary.Hex;
public class MacTest {
public static String TEST_DATA = "I am test";
public static void main(String[] args) throws NoSuchAlgorithmException, InvalidKeyException {
// TODO Auto-generated method stub
Mac mac = Mac.getInstance("HmacSHA1");
print(mac);
mac = Mac.getInstance("HmacMD5");
print(mac);
mac = Mac.getInstance("SslMacMD5");
print(mac);
mac = Mac.getInstance("HmacSHA384");
print(mac);
mac = Mac.getInstance("HmacSHA256");
print(mac);
mac = Mac.getInstance("HmacSHA224");
print(mac);
mac = Mac.getInstance("SslMacSHA1");
print(mac);
mac = Mac.getInstance("HmacSHA512");
print(mac);
}
private static void print(Mac mac) throws NoSuchAlgorithmException, InvalidKeyException {
System.out.println("Algorithm: " + mac.getAlgorithm());
System.out.println(" Provider: " + mac.getProvider());
KeyGenerator kg = KeyGenerator.getInstance("DES");
SecretKey key = kg.generateKey();
long start = System.nanoTime();
mac.init(key);
mac.update(TEST_DATA.getBytes());
byte[] digest = mac.doFinal();
long time = System.nanoTime() - start;
System.out.println(" Time cost: " + time + "ns");
System.out.println(" Byte length: " + digest.length);
String digestBase64Str = Base64.getEncoder().encodeToString(digest);
System.out.println(" Base64: " + digestBase64Str + " len: " + digestBase64Str.length());
String digestHexStr = Hex.encodeHexString(digest);
System.out.println(" Hex: " + digestHexStr + " len: " + digestHexStr.length());
}
}
輸出如下:
Algorithm: HmacSHA1
Provider: SunJCE version 1.8
Time cost: 259396ns
Byte length: 20
Base64: SVaesT3JpL9Emz5O40aZhpUrX5s= len: 28
Hex: 49569eb13dc9a4bf449b3e4ee3469986952b5f9b len: 40
Algorithm: HmacMD5
Provider: SunJCE version 1.8
Time cost: 136070ns
Byte length: 16
Base64: hBDkDPJ1CpyYqvFN48chqQ== len: 24
Hex: 8410e40cf2750a9c98aaf14de3c721a9 len: 32
Algorithm: SslMacMD5
Provider: SunJCE version 1.8
Time cost: 174089ns
Byte length: 16
Base64: YiEubyE7y+M4JesHQOAV7A== len: 24
Hex: 62212e6f213bcbe33825eb0740e015ec len: 32
Algorithm: HmacSHA384
Provider: SunJCE version 1.8
Time cost: 648249ns
Byte length: 48
Base64: GLic/lwKBA1DdQVbNF5y7L/H8o+0gcO1n02JcdUJMnE9MRwyfHWamEsAJL3ycfFy len: 64
Hex: 18b89cfe5c0a040d4375055b345e72ecbfc7f28fb481c3b59f4d8971d50932713d311c327c759a984b0024bdf271f172 len: 96
Algorithm: HmacSHA256
Provider: SunJCE version 1.8
Time cost: 26007ns
Byte length: 32
Base64: 7LGdb6W8WPYfOXx0WQQ8f35zSGCxs/6op6eOqStuGxA= len: 44
Hex: ecb19d6fa5bc58f61f397c7459043c7f7e734860b1b3fea8a7a78ea92b6e1b10 len: 64
Algorithm: HmacSHA224
Provider: SunJCE version 1.8
Time cost: 125344ns
Byte length: 28
Base64: adoBxnZuCle/ip4FyfCgiQUCmlaN1+RDch9Q9g== len: 40
Hex: 69da01c6766e0a57bf8a9e05c9f0a08905029a568dd7e443721f50f6 len: 56
Algorithm: SslMacSHA1
Provider: SunJCE version 1.8
Time cost: 50672ns
Byte length: 20
Base64: RxCsQguxNXgtqcobgqWdvJeYTKo= len: 28
Hex: 4710ac420bb135782da9ca1b82a59dbc97984caa len: 40
Algorithm: HmacSHA512
Provider: SunJCE version 1.8
Time cost: 365908ns
Byte length: 64
Base64: /Vf5JsSle43/t4aUMkDfdDeUFg3CA0OQAt5izo0bgoUmaVrVOv3tjTLwmrrL/3kACVn38aIDSAIlz8725gl6lA== len: 88
Hex: fd57f926c4a57b8dffb786943240df743794160dc203439002de62ce8d1b828526695ad53afded8d32f09abacbff79000959f7f1a203480225cfcef6e6097a94 len: 128
這裡使用的key是通過KeyGenerator生成的。在實際應用中,應該有一方來生成並匯出到可管理的KeyStore,使用方載入Keystore再進行摘要生成和校驗。
相關文章
- Android 安全加密:訊息摘要Message DigestAndroid加密
- Android安全加密:訊息摘要Message DigestAndroid加密
- MD5訊息摘要演算法演算法
- 密碼學系列——訊息摘要(c#程式碼實操)密碼學C#
- Java面試—訊息佇列Java面試佇列
- JMS java 訊息機制Java
- Java訊息佇列入門詳解Java佇列
- RocketMQ 訊息整合:多型別業務訊息-普通訊息MQ多型型別
- .NET Core加解密實戰系列之——訊息摘要與數字簽名演算法解密演算法
- RocketMQ 訊息整合:多型別業務訊息——定時訊息MQ多型型別
- 訊息機制篇——初識訊息與訊息佇列佇列
- 使用Java接入小程式訂閱訊息!Java
- Java多執行緒消費訊息Java執行緒
- java中如何捕獲鍵盤訊息Java
- java從SQS訂閱訊息 的demo, 要求保證訊息可靠投遞的例子Java
- 密碼學基礎:編碼方式、訊息摘要演算法、加密演算法總結密碼學演算法加密
- 解析 RocketMQ 業務訊息——“事務訊息”MQ
- 解析 RocketMQ 業務訊息--“順序訊息”MQ
- 自定義訊息獲取訊息(轉)
- java nio訊息半包、粘包解決方案Java
- JAVA訊息確認機制之ACK模式Java模式
- 死磕java底層(二)—訊息服務Java
- 使用 Java API 處理 WebSphere MQ 大訊息JavaAPIWebMQ
- Java中用Aeron實現UDP訊息傳遞JavaUDP
- 利用redis的hash結構搭建訊息服務(發訊息,訂閱訊息,消費訊息,退訂)Redis
- RocketMQ 原理:訊息儲存、高可用、訊息重試、訊息冪等性MQ
- 訊息中介軟體—RocketMQ訊息消費(三)(訊息消費重試)MQ
- 訊息中介軟體—RocketMQ訊息傳送MQ
- MQTT-保留訊息和遺囑訊息MQQT
- 自定義訊息和對訊息的理解
- SQLSTATE 訊息SQL
- Windows訊息Windows
- vue---元件間傳遞訊息(父子傳遞訊息,兄弟傳遞訊息)Vue元件
- Java訊息佇列三道面試題詳解!Java佇列面試題
- RabbitMQ訊息佇列(五):Routing 訊息路由MQ佇列路由
- OC訊息機制,訊息轉發機制
- Android訊息機制Message訊息池Android
- 深入解析MFC訊息響應和訊息路由路由