文档章节

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

王爵nice
 王爵nice
发布于 2015/04/01 11:18
字数 2453
阅读 25
收藏 0

一、简述

  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{
		//初始化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@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进制转换


© 著作权归作者所有

王爵nice

王爵nice

粉丝 286
博文 72
码字总数 72355
作品 5
浦东
程序员
私信 提问
Message Authentication Code_消息认证码算法

Message Authentication Code_消息认证码算法 内容来源于网络 部分内容摘自博客:http://blog.csdn.net/zzminer/article/details/8574287 MAC算法结合了MD5和SHA算法的优势,并加入密钥的支持...

秋风醉了
2014/07/14
0
1
java加密解密

秘钥 Key,分为对称密钥和非对称密钥 对称秘钥 SecretKey,由KeyGenerator生成 非对 PrivateKey,PublicKey,由KeyPairGenerator生成 KeyFactory(SecretKeyFactory)也可生成秘钥,可以将秘钥...

疯狂的骑士
2015/09/14
104
0
[Java 安全]消息摘要与数字签名

消息摘要 算法简述 定义 它是一个唯一对应一个消息或文本的固定长度的值,它由一个单向Hash加密函数对消息进行作用而产生。如果消息在途中改变了,则接收者通过对收到消息的新产生的摘要与原...

guitar_zp
2016/07/24
0
0
Java--Base64与消息摘要算法

Base64本质不是加密码算法。 安全和密码 常用安全体系 对称加密:指加密密钥与解密密钥相同。 非对称加密:指加密密钥与解密密钥不同,密钥分公钥、私钥。 散列函数:用来验证数据的完整性。...

BtWangZhi
03/31
0
0
SSL记录协议中的MAC

ssl的消息已经是加密的了,为何还要MAC,难道还有人会修改消息吗?如果怕有人修改消息,加一个摘要不就可以了吗?为何还要mac呢?这是怕有人离线攻击,我们可以信任协议本身,但是却不能信任...

晨曦之光
2012/04/10
727
0

没有更多内容

加载失败,请刷新页面

加载更多

06_CSS入门和高级技巧(4)

复习 CSS : 负责样式层,层叠式样式表cascading style sheet。CSS2.1,最新版本CSS3。 CSS选择器: 选择哪些元素加样式。基本选择3种:标签p、id选择器#id、class选择器.;高级选择器4种:后...

王裕杰
18分钟前
1
0
IT兄弟连 Java语法教程 变量2

变量的作用域和生命周期 到目前为止,使用的所有变量都是在main()方法开始时声明的,然而,Java允许在任何代码块(代码块以开花括号开始,以闭花括号结束)中声明变量,代码块定义了作用域。...

老码农的一亩三分地
54分钟前
3
0
OSChina 周二乱弹 —— 这份躺着挣钱的工作

Osc乱弹歌单(2019)请戳(这里) 【今日歌曲】 @巴拉迪维 :既然无法言说,不如一笑而过;既然无法释怀,不如安然自若。#今日歌曲推荐# 《Godi》- Lube 手机党少年们想听歌,请使劲儿戳(这...

小小编辑
今天
1K
21
Android沉浸式的两种方法

隐藏状态栏 一个Android应用程序的界面上其实是有很多系统元素的,观察下图: 而打造沉浸式模式的用户体验,就是要将这些系统元素全部隐藏,只留下主体内容部分。 怎么做呢,郭霖的一个Funct...

天王盖地虎626
今天
9
0
PostgreSQL build

https://buildfarm.postgresql.org/cgi-bin/show_log.pl?nm=lumpsucker&dt=2019-06-23%2020%3A57%3A27...

MtrS
今天
5
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部