訊息摘要演算法-MAC演算法系列

來源:互聯網
上載者:User

一、簡述

  mac(Message Authentication Code,訊息認證碼演算法)是含有密鑰散列函數演算法,相容了MD和SHA演算法的特性,並在此基礎上加上了密鑰。因此MAC演算法也經常被稱作HMAC演算法。關於hmac演算法的詳情可以參看RFC 2104(http://www.ietf.org/rfc/rfc2104.txt),這裡包含了HmacMD5演算法的C語言實現。

  這裡需要說明的是經過mac演算法得到的摘要值也可以使用十六進位編碼錶示,其摘要值得長度與實現演算法的摘要值長度相同。例如 HmacSHA演算法得到的摘要長度就是SHA1演算法得到的摘要長度,都是160位位元,換算成十六進位的編碼為40位。

 

二、模型分析

甲乙雙方進行資料交換可以採取如下流程完成

1、甲方向乙方公布摘要演算法(就是指定要使用的摘要演算法名)

2、甲乙雙方按照約定構造密鑰,雙方擁有相同的密鑰(一般是一方構造密鑰後通知另外一方,此過程不需要通過程式實現,就是雙方約定個字串,但是這個字串可不是隨便設定的,也是通過相關演算法擷取的)

3、甲方使用金鑰組訊息做摘要處理,然後將訊息和產生的摘要訊息一同發送給乙方

4、乙方收到訊息後,使用甲方已經公布的摘要演算法+約定好的密鑰 對收到的訊息進行摘要處理。然後比對自己的摘要訊息和甲方發過來的摘要訊息。甄別訊息是否是甲方發送過來的

 

三、MAC系列演算法支援表

 

演算法 摘要長度 備忘
HmacMD5 128 JAVA6實現
HmacSHA1 160 JAVA6實現
HmacSHA256 256 JAVA6實現
HmacSHA384 384 JAVA6實現
HmacSHA512 512 JAVA6實現
HmacMD2 128 BouncyCastle實現
HmacMD4 128 BouncyCastle實現
HmacSHA224 224 BouncyCastle實現

 

四、sun以及bouncycastle的hmac演算法實現

package com.ca.test;<br />import java.security.Security;<br />import javax.crypto.KeyGenerator;<br />import javax.crypto.Mac;<br />import javax.crypto.SecretKey;<br />import javax.crypto.spec.SecretKeySpec;<br />import org.bouncycastle.jce.provider.BouncyCastleProvider;<br />import org.bouncycastle.util.encoders.Hex;<br />/**<br /> * MAC訊息摘要組件<br /> * @author kongqz<br /> * */<br />public class MACCoder {<br />///////////////////////////HmacMD5///////////////////////////////<br />/**<br /> * 初始化HmacMD5的密鑰<br /> * @return byte[] 密鑰<br /> *<br /> * */<br />public static byte[] initHmacMD5Key() throws Exception{<br />//初始化KeyGenerator<br />KeyGenerator keyGenerator=KeyGenerator.getInstance("HmacMD5");<br />//產生密鑰<br />SecretKey secretKey=keyGenerator.generateKey();<br />//擷取密鑰<br />return secretKey.getEncoded();<br />}<br />/**<br /> * HmacMD5訊息摘要<br /> * @param data 待做摘要處理的資料<br /> * @param key 密鑰<br /> * @return byte[] 訊息摘要<br /> * */<br />public static byte[] encodeHmacMD5(byte[] data,byte[] key) throws Exception{<br />//還原密鑰,因為密鑰是以byte形式為訊息傳遞演算法所擁有<br />SecretKey secretKey=new SecretKeySpec(key,"HmacMD5");<br />//執行個體化Mac<br />Mac mac=Mac.getInstance(secretKey.getAlgorithm());<br />//初始化Mac<br />mac.init(secretKey);<br />//執行訊息摘要處理<br />return mac.doFinal(data);<br />}</p><p>///////////////////////////////HmacSHA1//////////////////////////////////<br />/**<br /> * 初始化HmacSHA1的密鑰<br /> * @return byte[] 密鑰<br /> *<br /> * */<br />public static byte[] initHmacSHAKey() throws Exception{<br />//初始化KeyGenerator<br />KeyGenerator keyGenerator=KeyGenerator.getInstance("HmacSHA1");<br />//產生密鑰<br />SecretKey secretKey=keyGenerator.generateKey();<br />//擷取密鑰<br />return secretKey.getEncoded();<br />}<br />/**<br /> * HmacSHA1訊息摘要<br /> * @param data 待做摘要處理的資料<br /> * @param key 密鑰<br /> * @return byte[] 訊息摘要<br /> * */<br />public static byte[] encodeHmacSHA(byte[] data,byte[] key) throws Exception{<br />//還原密鑰,因為密鑰是以byte形式為訊息傳遞演算法所擁有<br />SecretKey secretKey=new SecretKeySpec(key,"HmacSHA1");<br />//執行個體化Mac<br />Mac mac=Mac.getInstance(secretKey.getAlgorithm());<br />//初始化Mac<br />mac.init(secretKey);<br />//執行訊息摘要處理<br />return mac.doFinal(data);<br />}</p><p>///////////////////////////////HmacSHA256//////////////////////////////////<br />/**<br /> * 初始化HmacSHA256的密鑰<br /> * @return byte[] 密鑰<br /> *<br /> * */<br />public static byte[] initHmacSHA256Key() throws Exception{<br />//初始化KeyGenerator<br />KeyGenerator keyGenerator=KeyGenerator.getInstance("HmacSHA256");<br />//產生密鑰<br />SecretKey secretKey=keyGenerator.generateKey();<br />//擷取密鑰<br />return secretKey.getEncoded();<br />}<br />/**<br /> * HmacSHA256訊息摘要<br /> * @param data 待做摘要處理的資料<br /> * @param key 密鑰<br /> * @return byte[] 訊息摘要<br /> * */<br />public static byte[] encodeHmacSHA256(byte[] data,byte[] key) throws Exception{<br />//還原密鑰,因為密鑰是以byte形式為訊息傳遞演算法所擁有<br />SecretKey secretKey=new SecretKeySpec(key,"HmacSHA256");<br />//執行個體化Mac<br />Mac mac=Mac.getInstance(secretKey.getAlgorithm());<br />//初始化Mac<br />mac.init(secretKey);<br />//執行訊息摘要處理<br />return mac.doFinal(data);<br />}</p><p>///////////////////////////////HmacSHA384//////////////////////////////////<br />/**<br /> * 初始化HmacSHA384的密鑰<br /> * @return byte[] 密鑰<br /> *<br /> * */<br />public static byte[] initHmacSHA384Key() throws Exception{<br />//初始化KeyGenerator<br />KeyGenerator keyGenerator=KeyGenerator.getInstance("HmacSHA384");<br />//產生密鑰<br />SecretKey secretKey=keyGenerator.generateKey();<br />//擷取密鑰<br />return secretKey.getEncoded();<br />}<br />/**<br /> * HmacSHA384訊息摘要<br /> * @param data 待做摘要處理的資料<br /> * @param key 密鑰<br /> * @return byte[] 訊息摘要<br /> * */<br />public static byte[] encodeHmacSHA384(byte[] data,byte[] key) throws Exception{<br />//還原密鑰,因為密鑰是以byte形式為訊息傳遞演算法所擁有<br />SecretKey secretKey=new SecretKeySpec(key,"HmacSHA384");<br />//執行個體化Mac<br />Mac mac=Mac.getInstance(secretKey.getAlgorithm());<br />//初始化Mac<br />mac.init(secretKey);<br />//執行訊息摘要處理<br />return mac.doFinal(data);<br />}</p><p>///////////////////////////////HmacSHA512//////////////////////////////////<br />/**<br /> * 初始化HmacSHA512的密鑰<br /> * @return byte[] 密鑰<br /> *<br /> * */<br />public static byte[] initHmacSHA512Key() throws Exception{<br />//初始化KeyGenerator<br />KeyGenerator keyGenerator=KeyGenerator.getInstance("HmacSHA512");<br />//產生密鑰<br />SecretKey secretKey=keyGenerator.generateKey();<br />//擷取密鑰<br />return secretKey.getEncoded();<br />}<br />/**<br /> * HmacSHA512訊息摘要<br /> * @param data 待做摘要處理的資料<br /> * @param key 密鑰<br /> * @return byte[] 訊息摘要<br /> * */<br />public static byte[] encodeHmacSHA512(byte[] data,byte[] key) throws Exception{<br />//還原密鑰,因為密鑰是以byte形式為訊息傳遞演算法所擁有<br />SecretKey secretKey=new SecretKeySpec(key,"HmacSHA512");<br />//執行個體化Mac<br />Mac mac=Mac.getInstance(secretKey.getAlgorithm());<br />//初始化Mac<br />mac.init(secretKey);<br />//執行訊息摘要處理<br />return mac.doFinal(data);<br />}<br />///////////////////////////////HmacMD2-BouncyCastle才支援的實現//////////////////////////////////<br />/**<br /> * 初始化HmacMD2的密鑰<br /> * @return byte[] 密鑰<br /> * */<br />public static byte[] initHmacMD2Key() throws Exception{</p><p>//加入BouncyCastleProvider的支援<br />Security.addProvider(new BouncyCastleProvider());<br />//初始化KeyGenerator<br />KeyGenerator keyGenerator=KeyGenerator.getInstance("HmacMD2");<br />//產生密鑰<br />SecretKey secretKey=keyGenerator.generateKey();<br />//擷取密鑰<br />return secretKey.getEncoded();<br />}<br />/**<br /> * HmacMD2訊息摘要<br /> * @param data 待做摘要處理的資料<br /> * @param key 密鑰<br /> * @return byte[] 訊息摘要<br /> * */<br />public static byte[] encodeHmacMD2(byte[] data,byte[] key) throws Exception{<br />//加入BouncyCastleProvider的支援<br />Security.addProvider(new BouncyCastleProvider());<br />//還原密鑰,因為密鑰是以byte形式為訊息傳遞演算法所擁有<br />SecretKey secretKey=new SecretKeySpec(key,"HmacMD2");<br />//執行個體化Mac<br />Mac mac=Mac.getInstance(secretKey.getAlgorithm());<br />//初始化Mac<br />mac.init(secretKey);<br />//執行訊息摘要處理<br />return mac.doFinal(data);<br />}<br />/**<br /> * HmacMD2Hex訊息摘要<br /> * @param data 待做訊息摘要處理的資料<br /> * @param String 密鑰<br /> * @return byte[] 訊息摘要<br /> * */<br />public static String encodeHmacMD2Hex(byte[] data,byte[] key) throws Exception{<br />//執行訊息摘要處理<br />byte[] b=encodeHmacMD2(data,key);<br />//做十六進位轉換<br />return new String(Hex.encode(b));<br />}</p><p>///////////////////////////////HmacMD4-BouncyCastle才支援的實現//////////////////////////////////<br />/**<br /> * 初始化HmacMD2的密鑰<br /> * @return byte[] 密鑰<br /> * */<br />public static byte[] initHmacMD4Key() throws Exception{</p><p>//加入BouncyCastleProvider的支援<br />Security.addProvider(new BouncyCastleProvider());<br />//初始化KeyGenerator<br />KeyGenerator keyGenerator=KeyGenerator.getInstance("HmacMD4");<br />//產生密鑰<br />SecretKey secretKey=keyGenerator.generateKey();<br />//擷取密鑰<br />return secretKey.getEncoded();<br />}<br />/**<br /> * HmacMD4訊息摘要<br /> * @param data 待做摘要處理的資料<br /> * @param key 密鑰<br /> * @return byte[] 訊息摘要<br /> * */<br />public static byte[] encodeHmacMD4(byte[] data,byte[] key) throws Exception{<br />//加入BouncyCastleProvider的支援<br />Security.addProvider(new BouncyCastleProvider());<br />//還原密鑰,因為密鑰是以byte形式為訊息傳遞演算法所擁有<br />SecretKey secretKey=new SecretKeySpec(key,"HmacMD4");<br />//執行個體化Mac<br />Mac mac=Mac.getInstance(secretKey.getAlgorithm());<br />//初始化Mac<br />mac.init(secretKey);<br />//執行訊息摘要處理<br />return mac.doFinal(data);<br />}<br />/**<br /> * HmacMD4Hex訊息摘要<br /> * @param data 待做訊息摘要處理的資料<br /> * @param String 密鑰<br /> * @return byte[] 訊息摘要<br /> * */<br />public static String encodeHmacMD4Hex(byte[] data,byte[] key) throws Exception{<br />//執行訊息摘要處理<br />byte[] b=encodeHmacMD4(data,key);<br />//做十六進位轉換<br />return new String(Hex.encode(b));<br />}<br />///////////////////////////////HmacSHA224-BouncyCastle才支援的實現//////////////////////////////////<br />/**<br /> * 初始化HmacSHA224的密鑰<br /> * @return byte[] 密鑰<br /> * */<br />public static byte[] initHmacSHA224Key() throws Exception{</p><p>//加入BouncyCastleProvider的支援<br />Security.addProvider(new BouncyCastleProvider());<br />//初始化KeyGenerator<br />KeyGenerator keyGenerator=KeyGenerator.getInstance("HmacSHA224");<br />//產生密鑰<br />SecretKey secretKey=keyGenerator.generateKey();<br />//擷取密鑰<br />return secretKey.getEncoded();<br />}<br />/**<br /> * HmacSHA224訊息摘要<br /> * @param data 待做摘要處理的資料<br /> * @param key 密鑰<br /> * @return byte[] 訊息摘要<br /> * */<br />public static byte[] encodeHmacSHA224(byte[] data,byte[] key) throws Exception{<br />//加入BouncyCastleProvider的支援<br />Security.addProvider(new BouncyCastleProvider());<br />//還原密鑰,因為密鑰是以byte形式為訊息傳遞演算法所擁有<br />SecretKey secretKey=new SecretKeySpec(key,"HmacSHA224");<br />//執行個體化Mac<br />Mac mac=Mac.getInstance(secretKey.getAlgorithm());<br />//初始化Mac<br />mac.init(secretKey);<br />//執行訊息摘要處理<br />return mac.doFinal(data);<br />}<br />/**<br /> * HmacSHA224Hex訊息摘要<br /> * @param data 待做訊息摘要處理的資料<br /> * @param String 密鑰<br /> * @return byte[] 訊息摘要<br /> * */<br />public static String encodeHmacSHA224Hex(byte[] data,byte[] key) throws Exception{<br />//執行訊息摘要處理<br />byte[] b=encodeHmacSHA224(data,key);<br />//做十六進位轉換<br />return new String(Hex.encode(b));<br />}<br />/**<br /> * 進行相關的摘要演算法的處理展示<br /> * @throws Exception<br /> * **/<br />public static void main(String[] args) throws Exception {<br />String str="HmacMD5訊息摘要";<br />//初始化密鑰<br />byte[] key1=MACCoder.initHmacMD5Key();<br />//擷取摘要資訊<br />byte[] data1=MACCoder.encodeHmacMD5(str.getBytes(), key1);</p><p>System.out.println("原文:"+str);<br />System.out.println();<br />System.out.println("HmacMD5的密鑰:"+key1.toString());<br />System.out.println("HmacMD5演算法摘要:"+data1.toString());<br />System.out.println();</p><p>//初始化密鑰<br />byte[] key2=MACCoder.initHmacSHA256Key();<br />//擷取摘要資訊<br />byte[] data2=MACCoder.encodeHmacSHA256(str.getBytes(), key2);<br />System.out.println("HmacSHA256的密鑰:"+key2.toString());<br />System.out.println("HmacSHA256演算法摘要:"+data2.toString());<br />System.out.println();</p><p>//初始化密鑰<br />byte[] key3=MACCoder.initHmacSHAKey();<br />//擷取摘要資訊<br />byte[] data3=MACCoder.encodeHmacSHA(str.getBytes(), key3);<br />System.out.println("HmacSHA1的密鑰:"+key3.toString());<br />System.out.println("HmacSHA1演算法摘要:"+data3.toString());<br />System.out.println();</p><p>//初始化密鑰<br />byte[] key4=MACCoder.initHmacSHA384Key();<br />//擷取摘要資訊<br />byte[] data4=MACCoder.encodeHmacSHA384(str.getBytes(), key4);<br />System.out.println("HmacSHA384的密鑰:"+key4.toString());<br />System.out.println("HmacSHA384演算法摘要:"+data4.toString());<br />System.out.println();</p><p>//初始化密鑰<br />byte[] key5=MACCoder.initHmacSHA512Key();<br />//擷取摘要資訊<br />byte[] data5=MACCoder.encodeHmacSHA512(str.getBytes(), key5);<br />System.out.println("HmacSHA512的密鑰:"+key5.toString());<br />System.out.println("HmacSHA512演算法摘要:"+data5.toString());<br />System.out.println();</p><p>System.out.println("================以下的演算法支援是bouncycastle支援的演算法,sun java6不支援=======================");<br />//初始化密鑰<br />byte[] key6=MACCoder.initHmacMD2Key();<br />//擷取摘要資訊<br />byte[] data6=MACCoder.encodeHmacMD2(str.getBytes(), key6);<br />String datahex6=MACCoder.encodeHmacMD2Hex(str.getBytes(), key6);<br />System.out.println("Bouncycastle HmacMD2的密鑰:"+key6.toString());<br />System.out.println("Bouncycastle HmacMD2演算法摘要:"+data6.toString());<br />System.out.println("Bouncycastle HmacMD2Hex演算法摘要:"+datahex6.toString());<br />System.out.println();</p><p>//初始化密鑰<br />byte[] key7=MACCoder.initHmacMD4Key();<br />//擷取摘要資訊<br />byte[] data7=MACCoder.encodeHmacMD4(str.getBytes(), key7);<br />String datahex7=MACCoder.encodeHmacMD4Hex(str.getBytes(), key7);<br />System.out.println("Bouncycastle HmacMD4的密鑰:"+key7.toString());<br />System.out.println("Bouncycastle HmacMD4演算法摘要:"+data7.toString());<br />System.out.println("Bouncycastle HmacMD4Hex演算法摘要:"+datahex7.toString());<br />System.out.println();</p><p>//初始化密鑰<br />byte[] key8=MACCoder.initHmacSHA224Key();<br />//擷取摘要資訊<br />byte[] data8=MACCoder.encodeHmacSHA224(str.getBytes(), key8);<br />String datahex8=MACCoder.encodeHmacSHA224Hex(str.getBytes(), key8);<br />System.out.println("Bouncycastle HmacSHA224的密鑰:"+key8.toString());<br />System.out.println("Bouncycastle HmacSHA224演算法摘要:"+data8.toString());<br />System.out.println("Bouncycastle HmacSHA224演算法摘要:"+datahex8.toString());<br />System.out.println();<br />}<br />}<br />控制台輸出結果如下:<br />原文:HmacMD5訊息摘要<br />HmacMD5的密鑰:[B@136228<br />HmacMD5演算法摘要:[B@913750<br />HmacSHA256的密鑰:[B@bfbdb0<br />HmacSHA256演算法摘要:[B@3e86d0<br />HmacSHA1的密鑰:[B@253498<br />HmacSHA1演算法摘要:[B@9fef6f<br />HmacSHA384的密鑰:[B@f38798<br />HmacSHA384演算法摘要:[B@4b222f<br />HmacSHA512的密鑰:[B@b0f13d<br />HmacSHA512演算法摘要:[B@ae000d<br />================以下的演算法支援是bouncycastle支援的演算法,sun java6不支援=======================<br />Bouncycastle HmacMD2的密鑰:[B@4741d6<br />Bouncycastle HmacMD2演算法摘要:[B@337d0f<br />Bouncycastle HmacMD2Hex演算法摘要:0fbabb3bb1a2be81fbc823013f6920fe<br />Bouncycastle HmacMD4的密鑰:[B@1e0bc08<br />Bouncycastle HmacMD4演算法摘要:[B@158b649<br />Bouncycastle HmacMD4Hex演算法摘要:a3fa5935ca554f83c8987efd2bcfe605<br />Bouncycastle HmacSHA224的密鑰:[B@8a0d5d<br />Bouncycastle HmacSHA224演算法摘要:[B@173831b<br />Bouncycastle HmacSHA224演算法摘要:542d47250e5ff9f8bb3a7607799b1685a8accd65580410ea1d4dd578<br />

五、總結

 

1、sun支援了5中演算法,但是不支援轉成16進位,但是可以用commons codec或者bouncycastle的16進位轉換協助進行轉換

2、bouncycastle支援補充了三種演算法,並支援16進位轉換

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.