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

为什么80%的码农都做不了架构师?>>>   hot3.png

一、简述

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


转载于:https://my.oschina.net/biezhi/blog/394579

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/263618.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

软件开发七宗罪

导读:一起来看看世界各地的程序员们所共有的致命通病,从软件开发的地狱中拯救自己。这七宗罪你有几条? 想成为一名优秀的软件开发人员需要很长时间的培训和实践。但是如果不遵循合适的原则,即便是再好的程序员也会成为失败的牺牲品…

Spring Boot:快速入门教程

什么是Spring Boot? Spring Boot是由Pivotal团队提供的全新框架,其设计目的是用来简化新Spring应用的初始搭建以及开发过程。该框架使用了特定的方式来进行配置,从而使开发人员不再需要定义样板化的配置。简而言之,Spring Boot通过提供默认配…

移动微技(Mobile Widget)应用开发权威指南

移动微技(Mobile Widget)应用开发权威指南 基本信息 作者: 程宝平 杨晓华 朱春梅 丛书名: 中国移动创新系列丛书 出版社:电子工业出版社 ISBN:9787121104527 上架时间:2010-4-19 出版日…

Apache、Nginx、Tomcat的区别

Apache、Nginx、Tomcat的区别NginxTomcatApache,Nginx与Tomcat的区别Nginx -----是一个高性能的HTTP和反向代理服务器,也是一个IMAP/POP3/SMTP代理服务器。** Tomcat -----servlet(jsp)应用服务器 Tomcat是运行在JVM中的一个进程。它定义为“中间件”…

检索

【摘抄】基于线性表的检索一、检索的基本概念和算法分类1、检索概念: 可以形式化地定义基于关键码的检索。假定k1、k2…kn是互不相同的关键码值,有一个包含n条记录的集合C,形式如下: (k1, R1),(k2, R2),…

例说C#深拷贝与浅拷贝

一开始,先对C#深拷贝与浅拷贝知识做个简单的总结。 无论是浅拷贝与深拷贝,C#都将源对象中的所有字段复制到新的对象中。不过,对于值类型字段,引用类型字段以及字符串类型字段的处理,两种拷贝方式存在一定的区别&#x…

企业架构 - 开篇:TOGAF介绍

在《年度总结和计划:去年4个1,今年5个1》中说过今年我准备在项目组引入一个架构方TOGAF。工业和信息化部副部长杨学山在一次内部座谈时提到:与西方发达国家比,国内的信息化建设在硬件方面已经不相上下,在软件方面有5年…

C#(4) implicit explicit

最近几节课学的知识点的量有很大增长,加上上机和托福考试的临近,这里练习的所有代码就不走形式全贴出来了,找我自己觉得又不熟悉的点贴出来,争取简明扼要,恩恩 这次主要看接口的问题: 接口可以多继承&#…

【jquery】基于 jquery 实现 ie 浏览器兼容 placeholder 效果

placeholder 是 html5 新增加的属性,主要提供一种提示(hint),用于描述输入域所期待的值。该提示会在输入字段为空时显示,并会在字段获得焦点时消失。placeholder 属性适用于以下类型的 input 标签:text, se…

连接远程电脑中的虚拟机---端口映射

连接远程电脑中的虚拟机---端口映射问题:A主机中运行有2台虚拟机,现在我们希望在B主机中通过ssh(或其他方式)访问A主机中的2台虚拟机。(前提:B主机可以ping通A主机,即A有公网IP或A、B在同一子网下) 解决方法 设置虚拟…

Unity 动画属性

在动画的使用上使用不当的设置往往会造成不可预料的结果。 首先,如果动画自身可以驱动物体移动,那么在Animator组件上必须选择apply root motion,物体的动画位移才能生效,否则动画只能在原地播放。 第二,Bake Into Pos…

Javascript正则匹配数字,中英文,中横线,下划线,utf-8中文

为什么80%的码农都做不了架构师?>>> function check_string(nickname) {var reg /^[A-Za-z0-9-_\u4e00-\u9fa5]{4,30}$/;if (!reg.test(nickname)) {return false;}return true; } 转载于:https://my.oschina.net/biezhi/blog/396989

基于linux的集群系统LVS

一 LVS (Linux Virtual Server)针对高可伸缩、高可用网络服务的需求,我们给出了基于IP层和基于内容请求分发的负载平衡调度解决方法,并在Linux内核中实现了这些方法,将一组服务器构成一个实现可伸缩的、高可用网络服务…

jQuery 开发环境搭配(转)

jQuery 作为一个轻量级的 JavaScript 库,至 06 年出来到现在, 也算是用得最火的 JavaScript 库了吧, 要开始学习 jQuery ,首先还是必须得把环境搭配好吧, 这一篇博文呢,主要是想介绍一下在 Dreamweaver 上和…

Connection to node 0 (/192.168.204.131:9092) could not be established

解决连接虚拟机内kafka出现Connection to node 0 /192.168.204.131:9092 could not be established.Broker may not be available.问题: 在我尝试使用Springboot集成虚拟机内运行的kafka服务器时,出现了以下问题。 原因:可能出现的原因主要有…

获取本机MSSQL保存凭证

本文转自王子博客:http://www.cnblogs.com/killbit/p/4355950.html 首先要感谢哥们对我的指点,多谢。 当我们遇到类似情况下,如何获取保存在MSSQL工具里的凭证呢? //如果对方连接地址后面加了IP\sqlexpress 连接的时候你也记得加上…

【读书笔记-数据挖掘概念与技术】数据挖掘的发展趋势和研究前沿

复杂的数据类型 数据挖掘的其他方法 关于数据挖掘基础的观点: 可视和听觉数据挖掘 数据可视化数据挖掘结构可视化数据挖掘过程可视化交互式可视数据挖掘数据挖掘的应用

解决torch.cuda.is_available()为False的问题

解决torch.cuda.is_available为False问题:在Anaconda环境下,电脑拥有GPU并且已经通过conda install安装了Pytorch、cudatoolkit,但是torch.cuda.is_available()始终返回False(找不到显卡) 原因:使用conda …

如何解决ORA-04031错误

诊断并解决ORA-04031错误 当我们在共享池中试图分配大片的连续内存失败的时候,Oracle首先清除池中当前没使用的所有对象,使空闲内存块合并。如果仍然没有足够大单个的大块内存满足请求,就会产生ORA-04031错误。 当这个错误出现的时候你得到的…

Idea新建modules后无法自动导入pom.xml

Idea新建modules后无法自动导入pom.xml打开设置,搜索Maven,打开Importing,将红色箭头部分勾选 打开Ignored Files,将红色箭头部分都取消勾选 点击右侧工具栏的maven选项,点击红色箭头部分的Reimport All Maven Proje…