消息摘要算法-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,一经查实,立即删除!

相关文章

对Xml文档进行操作(修改,删除)

<?xml version"1.0" encoding"utf-8"?><Products> <Product id"0" proName"aa1" proPrice"12" proInfo"bb"> </Product> <Product id"1" proName"电脑" pro…

获取真实IP

真正的取真实IP地址及利弊(转自百度空间)目前网上流行的所谓“取真实IP地址”的方法&#xff0c;都有bug&#xff0c;没有考虑到多层透明代理的情况。 多数代码类似&#xff1a; string IpAddress (HttpContext.Current.Request.ServerVariables["HTTP_X_FORWARDED_FOR&q…

Java 中的位运算

移位运算符 包括&#xff1a; “>> 右移”&#xff1b;“<< 左移”&#xff1b;“>>> 无符号右移” 例子&#xff1a;-5>>3-11111 1111 1111 1111 1111 1111 1111 10111111 1111 1111 1111 1111 1111 1111 1111其结果与 Math.floor((double)-5/(…

[转]C++中的三种继承public,protected,private

链接&#xff1a;http://www.cnblogs.com/BeyondAnyTime/archive/2012/05/23/2514964.html

软件开发七宗罪

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

Spring Boot:快速入门教程

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

loadruner11 socket脚本-10053错误

背景: socket 10053异常&#xff1a;软件主动放弃一个连接&#xff0c;原因是超时或协议错误。如果LR客户端报10053异常&#xff0c;说明LR在执行套接字操作时&#xff0c;发生通信超时、网络中断或其它异常&#xff0c;主动将Socket连接断开。也就是说&#xff1a;10053异常是…

万网独享主机Apache为Ecshop商城添加404页面详解

在博客园基本都是做看客的角色&#xff0c;自己基本都没写过文章&#xff0c;不过昨天的经历确实让我有想法了&#xff0c;因为在网络上面看了很多文章&#xff0c;每篇写的都相对较片面&#xff0c;对于我这个Linux新手来说不免有点分不清东南西北&#xff0c;一不小心就浪费了…

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

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

[转载]Informix Dynamic Server维护手册

转载于:https://www.cnblogs.com/zgqjymx/archive/2011/03/06/1972733.html

Java反编译器Java Decompiler

Java Decompiler不仅为Windows、Linux、OSX系统提供GUI程序JD-GUI&#xff0c;而且还提供了Eclipse插件JD-Eclipse&#xff0c;官方网站&#xff1a;http://java.decompiler.free.fr/转载于:https://www.cnblogs.com/heroking2000/archive/2009/10/12/1582120.html

alternatives命令使用方法

alternatives命令使用方法 alternatives是Linux下的一个功能强大的命令。仅仅能在root权限下运行。如系统中有几个命令功能十分相似&#xff0c;却又不能任意删除&#xff0c;那么能够用 alternatives 来指定一个全局的设置。alternatives经常使用于同一个系统中安装同一软件的…

linux下挂接fat32分区

作者: Eulogize 出自: http://www.linuxdiyf.com Coolinux 在/mnt 下新建一个文件夹&#xff0c;命名可以随意&#xff0c;如D等。然落伍入终端输出上面的饬令#mount -t vfat -o codepage936 iocharsetgb2312 /hdv/hdX /mnt/dX在LINUX下的实体名&#xff0c;如Chda1版权声明…

Apache、Nginx、Tomcat的区别

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

python中通过元类(TYPE)简单实现对象关系映射(ORM)

ORM是创建一个实例对象&#xff0c;用创建他的类名当做数据表名&#xff0c;用创建他的类属性对应数据表的字段&#xff0c;不需要在自己写复杂的sql语句&#xff0c;而是通过对实例对象的操作时&#xff0c;能让代码自动帮我们整理为对应的sql语句。 class User(父类):uid (&…

ORA-12519: TNS:no appropriate service handler found 解决

selectcount(*) fromv$process --当前的连接数selectvalue fromv$parameter wherename processes--数据库允许的最大连接数修改最大连接数:altersystem setprocesses 300scope spfile;重启数据库:shutdownimmediate;startup;--查看当前有哪些用户正在使用数据SELECTosuser, a.u…

Linux下Web效力器架设攻略-1

来日诰日我们来看看怎样将Web效力器架在Linux零碎下。    LINUX零碎中罕见的有&#xff1a;CERN、NCSA、Apache三种体式格式&#xff0c;浅显最常用的要领就是用Apache。此种体式格式特点分明&#xff0c;设置装备部署简明&#xff0c;具有最大的对零碎兼容性&#xff0c;以…

Codeforces 1188A 构造

题意&#xff1a;给你一颗树&#xff0c;树的边权都是偶数&#xff0c;并且边权各不相同。你可以选择树的两个叶子结点&#xff0c;并且把两个叶子结点之间的路径加上一个值&#xff08;可以为负数&#xff09;&#xff0c;问是否可以通过这种操作构造出这颗树&#xff1f;如果…

iOS- 关于AVAudioSession的使用——后台播放音乐

1.前言   •AVAudioSession是一个单例&#xff0c;无需实例化即可直接使用。AVAudioSession在各种音频环境中起着非常重要的作用•针对不同的音频应用场景&#xff0c;需要设置不同的音频会话分类1.1AVAudioSession的类别   •AVAudioSessionCategoryAmbient–混音播放&…

检索

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