消息摘要算法-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系列算法支持表

算法 摘要长度 备注
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 <a href="http://lib.csdn.net/base/java" class=‘replace_word‘ title="Java 知识库" target=‘_blank‘ style=‘color:#df3434; font-weight:bold;‘>Java</a>.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的密钥:[[email protected]
HmacMD5算法摘要:[[email protected]0
HmacSHA256的密钥:[[email protected]
HmacSHA256算法摘要:[[email protected]
HmacSHA1的密钥:[[email protected]
HmacSHA1算法摘要:[[email protected]
HmacSHA384的密钥:[[email protected]
HmacSHA384算法摘要:[[email protected]
HmacSHA512的密钥:[[email protected]
HmacSHA512算法摘要:[[email protected]
================以下的算法支持是bouncycastle支持的算法,sun java6不支持=======================
Bouncycastle HmacMD2的密钥:[[email protected]
Bouncycastle HmacMD2算法摘要:[[email protected]
Bouncycastle HmacMD2Hex算法摘要:0fbabb3bb1a2be81fbc823013f6920fe
Bouncycastle HmacMD4的密钥:[[email protected]
Bouncycastle HmacMD4算法摘要:[[email protected]
Bouncycastle HmacMD4Hex算法摘要:a3fa5935ca554f83c8987efd2bcfe605
Bouncycastle HmacSHA224的密钥:[[email protected]
Bouncycastle HmacSHA224算法摘要:[[email protected]
Bouncycastle HmacSHA224算法摘要:542d47250e5ff9f8bb3a7607799b1685a8accd65580410ea1d4dd578

五、总结

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

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

时间: 2024-10-10 00:17:53

消息摘要算法-MAC算法系列的相关文章

消息摘要算法-HMAC算法

一.简述 mac(Message Authentication Code,消息认证码算法)是含有密钥散列函数算法,兼容了MD和SHA算法的特性,并在此基础上加上了密钥.因此MAC算法也经常被称作HMAC算法.关于hmac算法的详情可以参看RFC 2104(http://www.ietf.org/rfc/rfc2104.txt),这里包含了HmacMD5算法的C语言实现. 这里需要说明的是经过mac算法得到的摘要值也可以使用十六进制编码表示,其摘要值得长度与实现算法的摘要值长度相同.例如 Hmac

Apache Commons Codec 与消息摘要算法(hash算法)

首先我们要明白 Codec 是什么含义.它是 Coder + decoder = Codec,也就是编码器解码器.即是编码器,也是解码器. 官网地址:http://commons.apache.org/proper/commons-codec/ Apache Commons Codec (TM) software provides implementations of common encoders and decoders such as Base64, Hex, Phonetic and U

密码学4——Java 加密解密之消息摘要算法(MD5 SHA MAC)

Java 加密解密之消息摘要算法(MD5 SHA MAC) 消息摘要 消息摘要(Message Digest)又称为数字摘要(Digital Digest).它是一个唯一对应一个消息或文本的固定长度的值,它由一个单向Hash加密函数对消息进行作用而产生.如果消息在途中改变了,则接收者通过对收到消息的新产生的摘要与原摘要比较,就可知道消息是否被改变了.因此消息摘要保证了消息的完整性.消息摘要采用单向Hash 函数将需加密 的明文"摘要"成一串128bit的密文,这一串密文亦称为数字指纹(

信息加密之消息摘要算法的MAC

MAC是消息摘要算法的第三种实现方式,另外两种方式分别为:MD2\4\5.SHA. MAC的jdk实现:1.默认密钥方式 private static void MAC_JDK(){ try { KeyGenerator keyGenerator = KeyGenerator.getInstance("HmacMD5");//初始化KeyGenerator SecretKey secretKey = keyGenerator.generateKey();//产生密钥 byte[] ke

列出本机JCE提供者,支持消息摘要算法,支持公钥私钥算法

import java.security.Provider; import java.security.Security; public class TestBouncyCastle { public static void main(String[] args) { Provider[] providers = Security.getProviders(); for(Provider p : providers){ System.out.println("提供者名称:"+p.get

算法系列6——MAC

GP中定义的MAC可以和PBOC中的MAC通过简单计算相互转换,如下: DATA=84820000100102030405060708800000 ICV=0000000000000000 KEY=404142434445464748494A4B4C4D4E4F 安全通道协议标识ALGSCP=02 3DES_MAC_1为PBOC中规定的计算MAC方法 3DES_MAC_1(ICV+DATA,KEY,MAC1)//MAC1=106729A5F51BFC24 GP_MAC为GP中规定的计算MAC方法

消息摘要算法

消息摘要算法: 1)MD(Message Digest)消息摘要 2)SHA(Secure Hash Algorithm) 安全散列算法 3)  MAC(Message Authentication Code)消息认证码 消息摘要算法主要作用是:验证数据的完整性 消息摘要算法是数字签名的核心算法

MD5 Message Digest Algorithm MD5(中文名为消息摘要算法第五版)

MD5 编辑 Message Digest Algorithm MD5(中文名为消息摘要算法第五版)为计算机安全领域广泛使用的一种散列函数,用以提供消息的完整性保护.该算法的文件号为RFC 1321(R.Rivest,MIT Laboratory for Computer Science and RSA Data Security Inc. April 1992). MD5即Message-Digest Algorithm 5(信息-摘要算法5),用于确保信息传输完整一致.是计算机广泛使用的杂凑

常用消息摘要算法介绍

消息摘要算法 介绍: 数据摘要算法是密码学算法中非常重要的一个分支,它通过对所有数据提取指纹信息以实现数据签名.数据完整性校验等功能,由于其不可逆性,有时候会被用做敏感信息的加密.数据摘要算法也被称为哈希(Hash)算法或散列算法. 消息摘要算法的主要特征是加密过程不需要密钥,并且经过加密的数据无法被解密,只有输入相同的明文数据经过相同的消息摘要算法才能得到相同的密文.(摘要可以比方为指纹,消息摘要算法就是要得到文件的唯一职位) 特点: 无论输入的消息有多长,计算出来的消息摘要的长度总是固定的.