come from: http://blog.csdn.net/lonelyroamer/article/details/7630594
一、概述
MAC演算法結合了MD5和SHA演算法的優勢,並加入密鑰的支援,是一種更為安全的訊息摘要演算法。
MAC(Message Authentication Code,訊息認證碼演算法)是含有密鑰的散列函數演算法,相容了MD和SHA演算法的特性,並在此基礎上加入了密鑰。日次,我們也常把MAC稱為HMAC(keyed-Hash Message Authentication Code)。
MAC演算法主要集合了MD和SHA兩大系列訊息摘要演算法。MD系列的演算法有HmacMD2、HmacMD4、HmacMD5三種演算法;SHA系列的演算法有HmacSHA1、HmacSHA224、HmacSHA256、HmacSHA384.HmacSHA512五種演算法。
經過MAC演算法得到的摘要值也可以使用十六進位編碼錶示,其摘要值長度與參與實現的摘要值長度相同。例如,HmacSHA1演算法得到的摘要長度就是SHA1演算法得到的摘要長度,都是160位二進位碼,換算成十六進位編碼為40位。
二、實現和應用
1、Sun的實現和應用
在java6中,MAC系列演算法需要通過Mac類提供支援。java6中僅僅提供HmacMD5、HmacSHA1、HmacSHA256、HmacSHA384和HmacSHA512四種演算法。
Mac演算法是帶有密鑰的訊息摘要演算法,所以實現起來要分為兩步:
1)、構建密鑰
2)、執行訊息摘要
[java] view plain copy print ? package com.tao.test; import java.security.NoSuchAlgorithmException; import javax.crypto.KeyGenerator; import javax.crypto.Mac; import javax.crypto.SecretKey; import javax.crypto.spec.SecretKeySpec; import javax.xml.bind.annotation.adapters.HexBinaryAdapter; /** * MAC演算法工具類 * 對於HmacMD5、HmacSHA1、HmacSHA256、HmacSHA384、HmacSHA512應用的步驟都是一模一樣的。具體看下面的代碼 */ class MACCoder { /** * 產生HmacMD5摘要演算法的密鑰 */ public static byte[] initHmacMD5Key() throws NoSuchAlgorithmException { // 初始化HmacMD5摘要演算法的密鑰產生器 KeyGenerator generator = KeyGenerator.getInstance("HmacMD5"); // 產生密鑰 SecretKey secretKey = generator.generateKey(); // 獲得密鑰 byte[] key = secretKey.getEncoded(); return key; } /** * HmacMd5摘要演算法 * 對於給定產生的不同密鑰,得到的摘要訊息會不同,所以在實際應用中,要儲存我們的密鑰 */ public static String encodeHmacMD5(byte[] data, byte[] key) throws Exception { // 還原密鑰 SecretKey secretKey = new SecretKeySpec(key, "HmacMD5"); // 執行個體化Mac Mac mac = Mac.getInstance(secretKey.getAlgorithm()); //初始化mac mac.init(secretKey); //執行訊息摘要 byte[] digest = mac.doFinal(data); return new HexBinaryAdapter().marshal(digest);//轉為十六進位的字串 } /** * 產生HmacSHA1摘要演算法的密鑰 */ public static byte[] initHmacSHAKey() throws NoSuchAlgorithmException { // 初始化HmacMD5摘要演算法的密鑰產生器 KeyGenerator generator = KeyGenerator.getInstance("HmacSHA1"); // 產生密鑰 SecretKey secretKey = generator.generateKey(); // 獲得密鑰 byte[] key = secretKey.getEncoded(); return key; } /** * HmacSHA1摘要演算法 * 對於給定產生的不同密鑰,得到的摘要訊息會不同,所以在實際應用中,要儲存我們的密鑰 */ public static String encodeHmacSHA(byte[] data, byte[] key) throws Exception { // 還原密鑰 SecretKey secretKey = new SecretKeySpec(key, "HmacSHA1"); // 執行個體化Mac Mac mac = Mac.getInstance(secretKey.getAlgorithm()); //初始化mac mac.init(secretKey); //執行訊息摘要 byte[] digest = mac.doFinal(data); return new HexBinaryAdapter().marshal(digest);//轉為十六進位的字串 } /** * 產生HmacSHA256摘要演算法的密鑰 */ public static byte[] initHmacSHA256Key() throws NoSuchAlgorithmException { // 初始化HmacMD5摘要演算法的密鑰產生器 KeyGenerator generator = KeyGenerator.getInstance("HmacSHA256"); // 產生密鑰 SecretKey secretKey = generator.generateKey(); // 獲得密鑰 byte[] key = secretKey.getEncoded(); return key; } /** * HmacSHA1摘要演算法 * 對於給定產生的不同密鑰,得到的摘要訊息會不同,所以在實際應用中,要儲存我們的密鑰 */ public static String encodeHmacSHA256(byte[] data, byte[] key) throws Exception { // 還原密鑰 SecretKey secretKey = new SecretKeySpec(key, "HmacSHA256"); // 執行個體化Mac Mac mac = Mac.getInstance(secretKey.getAlgorithm()); //初始化mac mac.init(secretKey); //執行訊息摘要 byte[] digest = mac.doFinal(data); return new HexBinaryAdapter().marshal(digest);//轉為十六進位的字串 } /** * 產生HmacSHA256摘要演算法的密鑰 */ public static byte[] initHmacSHA384Key() throws NoSuchAlgorithmException { // 初始化HmacMD5摘要演算法的密鑰產生器 KeyGenerator generator = KeyGenerator.getInstance("HmacSHA384"); // 產生密鑰 SecretKey secretKey = generator.generateKey(); // 獲得密鑰 byte[] key = secretKey.getEncoded(); return key; } /** * HmacSHA1摘要演算法 * 對於給定產生的不同密鑰,得到的摘要訊息會不同,所以在實際應用中,要儲存我們的密鑰 */ public static String encodeHmacSHA384(byte[] data, byte[] key) throws Exception { // 還原密鑰 SecretKey secretKey = new SecretKeySpec(key, "HmacSHA384"); // 執行個體化Mac Mac mac = Mac.getInstance(secretKey.getAlgorithm()); //初始化mac mac.init(secretKey); //執行訊息摘要 byte[] digest = mac.doFinal(data); return new HexBinaryAdapter().marshal(digest);//轉為十六進位的字串 } /** * 產生HmacSHA256摘要演算法的密鑰 */ public static byte[] initHmacSHA512Key() throws NoSuchAlgorithmException { // 初始化HmacMD5摘要演算法的密鑰產生器 KeyGenerator generator = KeyGenerator.getInstance("HmacSHA512"); // 產生密鑰 SecretKey secretKey = generator.generateKey(); // 獲得密鑰 byte[] key = secretKey.getEncoded(); return key; } /** * HmacSHA1摘要演算法 * 對於給定產生的不同密鑰,得到的摘要訊息會不同,所以在實際應用中,要儲存我們的密鑰 */ public static String encodeHmacSHA512(byte[] data, byte[] key) throws Exception { // 還原密鑰 SecretKey secretKey = new SecretKeySpec(key, "HmacSHA512"); // 執行個體化Mac Mac mac = Mac.getInstance(secretKey.getAlgorithm()); //初始化mac mac.init(secretKey); //執行訊息摘要 byte[] digest = mac.doFinal(data); return new HexBinaryAdapter().marshal(digest);//轉為十六進位的字串 } } public class MACTest { public static void main(String[] args) throws Exception { String testString = "asdasd"; byte[] keyHmacMD5=MACCoder.initHmacMD5Key(); System.out.println(MACCoder.encodeHmacMD5(testString.getBytes(),keyHmacMD5)); byte[] keyHmacSHA1=MACCoder.initHmacSHAKey(); System.out.println(MACCoder.encodeHmacSHA(testString.getBytes(),keyHmacSHA1)); byte[] keyHmacSHA256=MACCoder.initHmacSHA256Key(); System.out.println(MACCoder.encodeHmacSHA256(testString.getBytes(),keyHmacSHA256)); byte[] keyHmacSHA384=MACCoder.initHmacSHA384Key(); System.out.println(MACCoder.encodeHmacSHA384(testString.getBytes(),keyHmacSHA384)); byte[] keyHmacSHA512=MACCoder.initHmacSHA512Key(); System.out.println(MACCoder.encodeHmacSHA512(testString.getBytes(),keyHmacSHA512)); } }
package com.tao.test;import java.security.NoSuchAlgorithmException;import javax.crypto.KeyGenerator;import javax.crypto.Mac;import javax.crypto.SecretKey;import javax.crypto.spec.SecretKeySpec;import javax.xml.bind.annotation.adapters.HexBinaryAdapter;/** * MAC演算法工具類 * 對於HmacMD5、HmacSHA1、HmacSHA256、HmacSHA384、HmacSHA512應用的步驟都是一模一樣的。具體看下面的代碼 */class MACCoder {/** * 產生HmacMD5摘要演算法的密鑰 */public static byte[] initHmacMD5Key() throws NoSuchAlgorithmException {// 初始化HmacMD5摘要演算法的密鑰產生器KeyGenerator generator = KeyGenerator.getInstance("HmacMD5");// 產生密鑰SecretKey secretKey = generator.generateKey();// 獲得密鑰byte[] key = secretKey.getEncoded();return key;}/** * HmacMd5摘要演算法 * 對於給定產生的不同密鑰,得到的摘要訊息會不同,所以在實際應用中,要儲存我們的密鑰 */public static String encodeHmacMD5(byte[] data, byte[] key) throws Exception {// 還原密鑰SecretKey secretKey = new SecretKeySpec(key, "HmacMD5");// 執行個體化MacMac mac = Mac.getInstance(secretKey.getAlgorithm());//初始化macmac.init(secretKey);//執行訊息摘要byte[] digest = mac.doFinal(data);return new HexBinaryAdapter().marshal(digest);//轉為十六進位的字串}/** * 產生HmacSHA1摘要演算法的密鑰 */public static byte[] initHmacSHAKey() throws NoSuchAlgorithmException {// 初始化HmacMD5摘要演算法的密鑰產生器KeyGenerator generator = KeyGenerator.getInstance("HmacSHA1");// 產生密鑰SecretKey secretKey = generator.generateKey();// 獲得密鑰byte[] key = secretKey.getEncoded();return key;}/** * HmacSHA1摘要演算法 * 對於給定產生的不同密鑰,得到的摘要訊息會不同,所以在實際應用中,要儲存我們的密鑰 */public static String encodeHmacSHA(byte[] data, byte[] key) throws Exception {// 還原密鑰SecretKey secretKey = new SecretKeySpec(key, "HmacSHA1");// 執行個體化MacMac mac = Mac.getInstance(secretKey.getAlgorithm());//初始化macmac.init(secretKey);//執行訊息摘要byte[] digest = mac.doFinal(data);return new HexBinaryAdapter().marshal(digest);//轉為十六進位的字串}/** * 產生HmacSHA256摘要演算法的密鑰 */public static byte[] initHmacSHA256Key() throws NoSuchAlgorithmException {// 初始化HmacMD5摘要演算法的密鑰產生器KeyGenerator generator = KeyGenerator.getInstance("HmacSHA256");// 產生密鑰SecretKey secretKey = generator.generateKey();// 獲得密鑰byte[] key = secretKey.getEncoded();return key;}/** * HmacSHA1摘要演算法 * 對於給定產生的不同密鑰,得到的摘要訊息會不同,所以在實際應用中,要儲存我們的密鑰 */public static String encodeHmacSHA256(byte[] data, byte[] key) throws Exception {// 還原密鑰SecretKey secretKey = new SecretKeySpec(key, "HmacSHA256");// 執行個體化MacMac mac = Mac.getInstance(secretKey.getAlgorithm());//初始化macmac.init(secretKey);//執行訊息摘要byte[] digest = mac.doFinal(data);return new HexBinaryAdapter().marshal(digest);//轉為十六進位的字串}/** * 產生HmacSHA256摘要演算法的