消息摘要算法-MAC算法系列

一、简述

  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系列算法支持表

 

算法摘要长度备注
HmacMD5128JAVA6实现
HmacSHA1160JAVA6实现
HmacSHA256256JAVA6实现
HmacSHA384384JAVA6实现
HmacSHA512512JAVA6实现
HmacMD2128BouncyCastle实现
HmacMD4128BouncyCastle实现
HmacSHA224224BouncyCastle实现

 

四、sun以及bouncycastle的hmac算法实现

 

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{  
        //初始化KeyGenerator  
        KeyGenerator 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");  
        //实例化Mac  
        Mac mac=Mac.getInstance(secretKey.getAlgorithm());  
        //初始化Mac  
        mac.init(secretKey);  
        //执行消息摘要处理  
        return mac.doFinal(data);  
    }  
      
///HmacSHA1//  
    /** 
     * 初始化HmacSHA1的密钥 
     * @return byte[] 密钥 
     *  
     * */  
    public static byte[] initHmacSHAKey() throws Exception{  
        //初始化KeyGenerator  
        KeyGenerator 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");  
        //实例化Mac  
        Mac mac=Mac.getInstance(secretKey.getAlgorithm());  
        //初始化Mac  
        mac.init(secretKey);  
        //执行消息摘要处理  
        return mac.doFinal(data);  
    }  
      
///HmacSHA256//  
    /** 
     * 初始化HmacSHA256的密钥 
     * @return byte[] 密钥 
     *  
     * */  
    public static byte[] initHmacSHA256Key() throws Exception{  
        //初始化KeyGenerator  
        KeyGenerator 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");  
        //实例化Mac  
        Mac mac=Mac.getInstance(secretKey.getAlgorithm());  
        //初始化Mac  
        mac.init(secretKey);  
        //执行消息摘要处理  
        return mac.doFinal(data);  
    }  
      
///HmacSHA384//  
    /** 
     * 初始化HmacSHA384的密钥 
     * @return byte[] 密钥 
     *  
     * */  
    public static byte[] initHmacSHA384Key() throws Exception{  
        //初始化KeyGenerator  
        KeyGenerator 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");  
        //实例化Mac  
        Mac mac=Mac.getInstance(secretKey.getAlgorithm());  
        //初始化Mac  
        mac.init(secretKey);  
        //执行消息摘要处理  
        return mac.doFinal(data);  
    }  
      
///HmacSHA512//  
    /** 
     * 初始化HmacSHA512的密钥 
     * @return byte[] 密钥 
     *  
     * */  
    public static byte[] initHmacSHA512Key() throws Exception{  
        //初始化KeyGenerator  
        KeyGenerator 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");  
        //实例化Mac  
        Mac mac=Mac.getInstance(secretKey.getAlgorithm());  
        //初始化Mac  
        mac.init(secretKey);  
        //执行消息摘要处理  
        return mac.doFinal(data);  
    }  
///HmacMD2-BouncyCastle才支持的实现//  
    /** 
     * 初始化HmacMD2的密钥 
     * @return byte[] 密钥 
     * */  
    public static byte[] initHmacMD2Key() throws Exception{  
          
        //加入BouncyCastleProvider的支持  
        Security.addProvider(new BouncyCastleProvider());  
        //初始化KeyGenerator  
        KeyGenerator 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");  
        //实例化Mac  
        Mac mac=Mac.getInstance(secretKey.getAlgorithm());  
        //初始化Mac  
        mac.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());  
        //初始化KeyGenerator  
        KeyGenerator 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");  
        //实例化Mac  
        Mac mac=Mac.getInstance(secretKey.getAlgorithm());  
        //初始化Mac  
        mac.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());  
        //初始化KeyGenerator  
        KeyGenerator 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");  
        //实例化Mac  
        Mac mac=Mac.getInstance(secretKey.getAlgorithm());  
        //初始化Mac  
        mac.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@f3d6a5
HmacMD5算法摘要:[B@911f71

HmacSHA256的密钥:[B@1b10d42
HmacSHA256算法摘要:[B@dd87b2

HmacSHA1的密钥:[B@1a0c10f
HmacSHA1算法摘要:[B@e2eec8

HmacSHA384的密钥:[B@67ac19
HmacSHA384算法摘要:[B@53ba3d

HmacSHA512的密钥:[B@1813fac
HmacSHA512算法摘要:[B@7b7072

================以下的算法支持是bouncycastle支持的算法,sun java6不支持=======================
Bouncycastle HmacMD2的密钥:[B@1e4457d
Bouncycastle HmacMD2算法摘要:[B@18e2b22
Bouncycastle HmacMD2Hex算法摘要:103403efad9df90180d9c5528060950e

Bouncycastle HmacMD4的密钥:[B@efd552
Bouncycastle HmacMD4算法摘要:[B@19dfbff
Bouncycastle HmacMD4Hex算法摘要:9afc6aba973434b4092c9c4840dd0e41

Bouncycastle HmacSHA224的密钥:[B@16cd7d5
Bouncycastle HmacSHA224算法摘要:[B@cdedfd
Bouncycastle HmacSHA224算法摘要:293398d4bb063705dd2007be210022f40f34fb445fe4c1318ce4a550

 

五、总结

 

1、sun支持了5中算法,但是不支持转成16进制,但是可以用commons codec或者bouncycastle的16进制转换协助进行转换

2、bouncycastle支持补充了三种算法,并支持16进制转换

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值