消息摘要算法-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的密钥:[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进制转换
消息摘要算法-MAC算法系列的更多相关文章
- 消息摘要算法-HMAC算法
一.简述 mac(Message Authentication Code.消息认证码算法)是含有密钥散列函数算法.兼容了MD和SHA算法的特性,并在此基础上加上了密钥.因此MAC算法也常常被称作HMA ...
- 第五章 消息摘要算法--MAC
注意:本节内容主要参考自<Java加密与解密的艺术(第2版)>第6章“验证数据完整性--消息摘要算法” 5.1.mac(又称为Hmac) 原理:在md与sha系列算法的基础上加入了密钥,是 ...
- Apache Commons Codec 与消息摘要算法(hash算法)
首先我们要明白 Codec 是什么含义.它是 Coder + decoder = Codec,也就是编码器解码器.即是编码器,也是解码器. 官网地址:http://commons.apache.org ...
- MD、SHA、MAC消息摘要算法实现与应用
1.消息摘要概述 消息摘要(Message Digest)又称为数字摘要(Digital Digest).它是一个唯一对应一个消息或文本的固定长度的值,它由一个单向Hash加密函数对消息进行作用而产生 ...
- password学4——Java 加密解密之消息摘要算法(MD5 SHA MAC)
Java 加密解密之消息摘要算法(MD5 SHA MAC) 消息摘要 消息摘要(Message Digest)又称为数字摘要(Digital Digest). 它是一个唯一相应一个消息或文本的固定长度 ...
- 信息加密之消息摘要算法的MAC
MAC是消息摘要算法的第三种实现方式,另外两种方式分别为:MD2\4\5.SHA. MAC的jdk实现:1.默认密钥方式 private static void MAC_JDK(){ try { Ke ...
- MAC (Message Authentication Code,消息认证码算法)
需要将密钥发送到对方,对方用该密钥进行摘要处理,进行摘要验证. //初始化KeyGenerator KeyGenerator keyGenerator= KeyGenerator.getInstanc ...
- MAC算法
MAC算法 (Message Authentication Codes) 带秘密密钥的Hash函数:消息的散列值由只有通信双方知道的秘密密钥K来控制.此时Hash值称作MAC. 原理:在md与sha系 ...
- JAVA加解密 -- 消息摘要算法
消息摘要算法是一种单向加密算法 主要用于验证数据完整性,也是数字签名的核心算法 消息鉴别:指在接收方将原始信息进行摘要,然后与接收到的摘要信息进行对比 a.MD家族 – MD5(128位摘要信息) M ...
随机推荐
- vue学习笔记
来公司以后就一直在用vue框架,不管是业务代码,还是做vue组件.关于vue有一些点是文档中没有提及的,记录一下以便以后查询- 一.Vue的特点 新一代 Vue.js 框架非常关注如何用极少的外部特性 ...
- stray'\241'in program
stray '\241' in program : 该错误是指源程序中有非法字符,需要去掉非法字符.一般说来,如果你从其他地方复制代码过来,可能会出现这个问题.中文空格中文引号中文各种标点符号都会引起 ...
- JSP基础总结(运行机制、脚本元素、指令元素、动作元素)
JSP的运行机制: 1.转译阶段:JSP页面转换成Servlet类: 2.请求阶段:Servlet类执行,将相应结果发送至客户端. 流程解释: 1.用户访问某个JSP页面 2.服务器找到相应的JSP页 ...
- public/private/protected访问控制权限的区别
//public/private/protected访问控制权限的区别//时间:2016/8/16 //(一)修饰成员: //public: 在类内.类外都能使用 . //protected: 在类内 ...
- Hadoop集群搭建安装过程(一)(图文详解---尽情点击!!!)
Hadoop集群搭建(一)(上篇中讲到了Linux虚拟机的安装) 一.安装所需插件(以hadoop2.6.4为例,如果需要可以到官方网站进行下载:http://hadoop.apache.org) h ...
- HTML meta 标签用法(转)
meta主要为分HTTP标头信息(HTTP-EQUIV)和页面描述信息(NAME).标头信息包括文档类型.字符集.语言等浏览器正确显示网页的信息及处理动作:网页描述如内容的关键字.摘要.作者和定义ro ...
- 返回顶部demo
<!DOCTYPE html><html lang="en"> <head> <meta charset="UTF-8" ...
- eclipse修改web项目部署路径
Eclipse中用Tomcat发布的Web项目,更改其部署路径 我的Eclipse的工作目录是D:/workspace 先配置Tomcat 选择你的tomcat版本 点击next 这里先不要把项目添加 ...
- 破解版windows 7(旗舰版)下安装并使用vagrant统一开发环境
参考百度经验:http://jingyan.baidu.com/article/5553fa82c158bb65a23934be.html,事先对win7进行破解后的三个文件进行还原,否则会导致vir ...
- 论SCRM系统对传统行业的冲击
SCRM(Social Customer Relationship Management)顾名思义是社会型客户关系管理系统,这在当前的电子商务领域是一个创新的概念,由于社交媒体(Social Medi ...