消息摘要算法-MAC算法系列
為什么80%的碼農都做不了架構師?>>> ??
一、簡述
? 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; import?java.security.Security; import?javax.crypto.KeyGenerator; import?javax.crypto.Mac; import?javax.crypto.SecretKey; import?javax.crypto.spec.SecretKeySpec; import?org.bouncycastle.jce.provider.BouncyCastleProvider; import?org.bouncycastle.util.encoders.Hex; /***?MAC消息摘要組件*?@author?kongqz*?*/ public?class?MACCoder?{ ///HmacMD5////***?初始化HmacMD5的密鑰*?@return?byte[]?密鑰*?*?*/public?static?byte[]?initHmacMD5Key()?throws?Exception{//初始化KeyGeneratorKeyGenerator?keyGenerator=KeyGenerator.getInstance("HmacMD5");//產生密鑰SecretKey?secretKey=keyGenerator.generateKey();//獲取密鑰return?secretKey.getEncoded();}/***?HmacMD5消息摘要*?@param?data?待做摘要處理的數據*?@param?key?密鑰*?@return??byte[]?消息摘要*?*/public?static?byte[]?encodeHmacMD5(byte[]?data,byte[]?key)?throws?Exception{//還原密鑰,因為密鑰是以byte形式為消息傳遞算法所擁有SecretKey?secretKey=new?SecretKeySpec(key,"HmacMD5");//實例化MacMac?mac=Mac.getInstance(secretKey.getAlgorithm());//初始化Macmac.init(secretKey);//執行消息摘要處理return?mac.doFinal(data);}///HmacSHA1///***?初始化HmacSHA1的密鑰*?@return?byte[]?密鑰*?*?*/public?static?byte[]?initHmacSHAKey()?throws?Exception{//初始化KeyGeneratorKeyGenerator?keyGenerator=KeyGenerator.getInstance("HmacSHA1");//產生密鑰SecretKey?secretKey=keyGenerator.generateKey();//獲取密鑰return?secretKey.getEncoded();}/***?HmacSHA1消息摘要*?@param?data?待做摘要處理的數據*?@param?key?密鑰*?@return??byte[]?消息摘要*?*/public?static?byte[]?encodeHmacSHA(byte[]?data,byte[]?key)?throws?Exception{//還原密鑰,因為密鑰是以byte形式為消息傳遞算法所擁有SecretKey?secretKey=new?SecretKeySpec(key,"HmacSHA1");//實例化MacMac?mac=Mac.getInstance(secretKey.getAlgorithm());//初始化Macmac.init(secretKey);//執行消息摘要處理return?mac.doFinal(data);}///HmacSHA256///***?初始化HmacSHA256的密鑰*?@return?byte[]?密鑰*?*?*/public?static?byte[]?initHmacSHA256Key()?throws?Exception{//初始化KeyGeneratorKeyGenerator?keyGenerator=KeyGenerator.getInstance("HmacSHA256");//產生密鑰SecretKey?secretKey=keyGenerator.generateKey();//獲取密鑰return?secretKey.getEncoded();}/***?HmacSHA256消息摘要*?@param?data?待做摘要處理的數據*?@param?key?密鑰*?@return??byte[]?消息摘要*?*/public?static?byte[]?encodeHmacSHA256(byte[]?data,byte[]?key)?throws?Exception{//還原密鑰,因為密鑰是以byte形式為消息傳遞算法所擁有SecretKey?secretKey=new?SecretKeySpec(key,"HmacSHA256");//實例化MacMac?mac=Mac.getInstance(secretKey.getAlgorithm());//初始化Macmac.init(secretKey);//執行消息摘要處理return?mac.doFinal(data);}///HmacSHA384///***?初始化HmacSHA384的密鑰*?@return?byte[]?密鑰*?*?*/public?static?byte[]?initHmacSHA384Key()?throws?Exception{//初始化KeyGeneratorKeyGenerator?keyGenerator=KeyGenerator.getInstance("HmacSHA384");//產生密鑰SecretKey?secretKey=keyGenerator.generateKey();//獲取密鑰return?secretKey.getEncoded();}/***?HmacSHA384消息摘要*?@param?data?待做摘要處理的數據*?@param?key?密鑰*?@return??byte[]?消息摘要*?*/public?static?byte[]?encodeHmacSHA384(byte[]?data,byte[]?key)?throws?Exception{//還原密鑰,因為密鑰是以byte形式為消息傳遞算法所擁有SecretKey?secretKey=new?SecretKeySpec(key,"HmacSHA384");//實例化MacMac?mac=Mac.getInstance(secretKey.getAlgorithm());//初始化Macmac.init(secretKey);//執行消息摘要處理return?mac.doFinal(data);}///HmacSHA512///***?初始化HmacSHA512的密鑰*?@return?byte[]?密鑰*?*?*/public?static?byte[]?initHmacSHA512Key()?throws?Exception{//初始化KeyGeneratorKeyGenerator?keyGenerator=KeyGenerator.getInstance("HmacSHA512");//產生密鑰SecretKey?secretKey=keyGenerator.generateKey();//獲取密鑰return?secretKey.getEncoded();}/***?HmacSHA512消息摘要*?@param?data?待做摘要處理的數據*?@param?key?密鑰*?@return??byte[]?消息摘要*?*/public?static?byte[]?encodeHmacSHA512(byte[]?data,byte[]?key)?throws?Exception{//還原密鑰,因為密鑰是以byte形式為消息傳遞算法所擁有SecretKey?secretKey=new?SecretKeySpec(key,"HmacSHA512");//實例化MacMac?mac=Mac.getInstance(secretKey.getAlgorithm());//初始化Macmac.init(secretKey);//執行消息摘要處理return?mac.doFinal(data);} ///HmacMD2-BouncyCastle才支持的實現///***?初始化HmacMD2的密鑰*?@return?byte[]?密鑰*?*/public?static?byte[]?initHmacMD2Key()?throws?Exception{//加入BouncyCastleProvider的支持Security.addProvider(new?BouncyCastleProvider());//初始化KeyGeneratorKeyGenerator?keyGenerator=KeyGenerator.getInstance("HmacMD2");//產生密鑰SecretKey?secretKey=keyGenerator.generateKey();//獲取密鑰return?secretKey.getEncoded();}/***?HmacMD2消息摘要*?@param?data?待做摘要處理的數據*?@param?key?密鑰*?@return??byte[]?消息摘要*?*/public?static?byte[]?encodeHmacMD2(byte[]?data,byte[]?key)?throws?Exception{//加入BouncyCastleProvider的支持Security.addProvider(new?BouncyCastleProvider());//還原密鑰,因為密鑰是以byte形式為消息傳遞算法所擁有SecretKey?secretKey=new?SecretKeySpec(key,"HmacMD2");//實例化MacMac?mac=Mac.getInstance(secretKey.getAlgorithm());//初始化Macmac.init(secretKey);//執行消息摘要處理return?mac.doFinal(data);}/***?HmacMD2Hex消息摘要*?@param?data?待做消息摘要處理的數據*?@param?String?密鑰*?@return?byte[]?消息摘要*?*/public?static?String?encodeHmacMD2Hex(byte[]?data,byte[]?key)?throws?Exception{//執行消息摘要處理byte[]?b=encodeHmacMD2(data,key);//做十六進制轉換return?new?String(Hex.encode(b));}///HmacMD4-BouncyCastle才支持的實現///***?初始化HmacMD2的密鑰*?@return?byte[]?密鑰*?*/public?static?byte[]?initHmacMD4Key()?throws?Exception{//加入BouncyCastleProvider的支持Security.addProvider(new?BouncyCastleProvider());//初始化KeyGeneratorKeyGenerator?keyGenerator=KeyGenerator.getInstance("HmacMD4");//產生密鑰SecretKey?secretKey=keyGenerator.generateKey();//獲取密鑰return?secretKey.getEncoded();}/***?HmacMD4消息摘要*?@param?data?待做摘要處理的數據*?@param?key?密鑰*?@return??byte[]?消息摘要*?*/public?static?byte[]?encodeHmacMD4(byte[]?data,byte[]?key)?throws?Exception{//加入BouncyCastleProvider的支持Security.addProvider(new?BouncyCastleProvider());//還原密鑰,因為密鑰是以byte形式為消息傳遞算法所擁有SecretKey?secretKey=new?SecretKeySpec(key,"HmacMD4");//實例化MacMac?mac=Mac.getInstance(secretKey.getAlgorithm());//初始化Macmac.init(secretKey);//執行消息摘要處理return?mac.doFinal(data);}/***?HmacMD4Hex消息摘要*?@param?data?待做消息摘要處理的數據*?@param?String?密鑰*?@return?byte[]?消息摘要*?*/public?static?String?encodeHmacMD4Hex(byte[]?data,byte[]?key)?throws?Exception{//執行消息摘要處理byte[]?b=encodeHmacMD4(data,key);//做十六進制轉換return?new?String(Hex.encode(b));} ///HmacSHA224-BouncyCastle才支持的實現///***?初始化HmacSHA224的密鑰*?@return?byte[]?密鑰*?*/public?static?byte[]?initHmacSHA224Key()?throws?Exception{//加入BouncyCastleProvider的支持Security.addProvider(new?BouncyCastleProvider());//初始化KeyGeneratorKeyGenerator?keyGenerator=KeyGenerator.getInstance("HmacSHA224");//產生密鑰SecretKey?secretKey=keyGenerator.generateKey();//獲取密鑰return?secretKey.getEncoded();}/***?HmacSHA224消息摘要*?@param?data?待做摘要處理的數據*?@param?key?密鑰*?@return??byte[]?消息摘要*?*/public?static?byte[]?encodeHmacSHA224(byte[]?data,byte[]?key)?throws?Exception{//加入BouncyCastleProvider的支持Security.addProvider(new?BouncyCastleProvider());//還原密鑰,因為密鑰是以byte形式為消息傳遞算法所擁有SecretKey?secretKey=new?SecretKeySpec(key,"HmacSHA224");//實例化MacMac?mac=Mac.getInstance(secretKey.getAlgorithm());//初始化Macmac.init(secretKey);//執行消息摘要處理return?mac.doFinal(data);}/***?HmacSHA224Hex消息摘要*?@param?data?待做消息摘要處理的數據*?@param?String?密鑰*?@return?byte[]?消息摘要*?*/public?static?String?encodeHmacSHA224Hex(byte[]?data,byte[]?key)?throws?Exception{//執行消息摘要處理byte[]?b=encodeHmacSHA224(data,key);//做十六進制轉換return?new?String(Hex.encode(b));}/***?進行相關的摘要算法的處理展示*?@throws?Exception?*?**/public?static?void?main(String[]?args)?throws?Exception?{String?str="HmacMD5消息摘要";//初始化密鑰byte[]?key1=MACCoder.initHmacMD5Key();//獲取摘要信息byte[]?data1=MACCoder.encodeHmacMD5(str.getBytes(),?key1);System.out.println("原文:"+str);System.out.println();System.out.println("HmacMD5的密鑰:"+key1.toString());System.out.println("HmacMD5算法摘要:"+data1.toString());System.out.println();//初始化密鑰byte[]?key2=MACCoder.initHmacSHA256Key();//獲取摘要信息byte[]?data2=MACCoder.encodeHmacSHA256(str.getBytes(),?key2);System.out.println("HmacSHA256的密鑰:"+key2.toString());System.out.println("HmacSHA256算法摘要:"+data2.toString());System.out.println();//初始化密鑰byte[]?key3=MACCoder.initHmacSHAKey();//獲取摘要信息byte[]?data3=MACCoder.encodeHmacSHA(str.getBytes(),?key3);System.out.println("HmacSHA1的密鑰:"+key3.toString());System.out.println("HmacSHA1算法摘要:"+data3.toString());System.out.println();//初始化密鑰byte[]?key4=MACCoder.initHmacSHA384Key();//獲取摘要信息byte[]?data4=MACCoder.encodeHmacSHA384(str.getBytes(),?key4);System.out.println("HmacSHA384的密鑰:"+key4.toString());System.out.println("HmacSHA384算法摘要:"+data4.toString());System.out.println();//初始化密鑰byte[]?key5=MACCoder.initHmacSHA512Key();//獲取摘要信息byte[]?data5=MACCoder.encodeHmacSHA512(str.getBytes(),?key5);System.out.println("HmacSHA512的密鑰:"+key5.toString());System.out.println("HmacSHA512算法摘要:"+data5.toString());System.out.println();System.out.println("================以下的算法支持是bouncycastle支持的算法,sun?java6不支持=======================");//初始化密鑰byte[]?key6=MACCoder.initHmacMD2Key();//獲取摘要信息byte[]?data6=MACCoder.encodeHmacMD2(str.getBytes(),?key6);String?datahex6=MACCoder.encodeHmacMD2Hex(str.getBytes(),?key6);System.out.println("Bouncycastle?HmacMD2的密鑰:"+key6.toString());System.out.println("Bouncycastle?HmacMD2算法摘要:"+data6.toString());System.out.println("Bouncycastle?HmacMD2Hex算法摘要:"+datahex6.toString());System.out.println();//初始化密鑰byte[]?key7=MACCoder.initHmacMD4Key();//獲取摘要信息byte[]?data7=MACCoder.encodeHmacMD4(str.getBytes(),?key7);String?datahex7=MACCoder.encodeHmacMD4Hex(str.getBytes(),?key7);System.out.println("Bouncycastle?HmacMD4的密鑰:"+key7.toString());System.out.println("Bouncycastle?HmacMD4算法摘要:"+data7.toString());System.out.println("Bouncycastle?HmacMD4Hex算法摘要:"+datahex7.toString());System.out.println();//初始化密鑰byte[]?key8=MACCoder.initHmacSHA224Key();//獲取摘要信息byte[]?data8=MACCoder.encodeHmacSHA224(str.getBytes(),?key8);String?datahex8=MACCoder.encodeHmacSHA224Hex(str.getBytes(),?key8);System.out.println("Bouncycastle?HmacSHA224的密鑰:"+key8.toString());System.out.println("Bouncycastle?HmacSHA224算法摘要:"+data8.toString());System.out.println("Bouncycastle?HmacSHA224算法摘要:"+datahex8.toString());System.out.println();} } 控制臺輸出結果如下: 原文:HmacMD5消息摘要 HmacMD5的密鑰:[B@136228 HmacMD5算法摘要:[B@913750 HmacSHA256的密鑰:[B@bfbdb0 HmacSHA256算法摘要:[B@3e86d0 HmacSHA1的密鑰:[B@253498 HmacSHA1算法摘要:[B@9fef6f HmacSHA384的密鑰:[B@f38798 HmacSHA384算法摘要:[B@4b222f HmacSHA512的密鑰:[B@b0f13d HmacSHA512算法摘要:[B@ae000d ================以下的算法支持是bouncycastle支持的算法,sun?java6不支持======================= Bouncycastle?HmacMD2的密鑰:[B@4741d6 Bouncycastle?HmacMD2算法摘要:[B@337d0f Bouncycastle?HmacMD2Hex算法摘要:0fbabb3bb1a2be81fbc823013f6920fe Bouncycastle?HmacMD4的密鑰:[B@1e0bc08 Bouncycastle?HmacMD4算法摘要:[B@158b649 Bouncycastle?HmacMD4Hex算法摘要:a3fa5935ca554f83c8987efd2bcfe605 Bouncycastle?HmacSHA224的密鑰:[B@8a0d5d Bouncycastle?HmacSHA224算法摘要:[B@173831b Bouncycastle?HmacSHA224算法摘要:542d47250e5ff9f8bb3a7607799b1685a8accd65580410ea1d4dd578五、總結
?
1、sun支持了5中算法,但是不支持轉成16進制,但是可以用commons codec或者bouncycastle的16進制轉換協助進行轉換
2、bouncycastle支持補充了三種算法,并支持16進制轉換
轉載于:https://my.oschina.net/biezhi/blog/394579
總結
以上是生活随笔為你收集整理的消息摘要算法-MAC算法系列的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 优化神器 beamoff
- 下一篇: 有意思的小学数学竞赛题-2