第五章 消息摘要算法--MAC
注意:本节内容主要参考自《Java加密与解密的艺术(第2版)》第6章“验证数据完整性--消息摘要算法”
5.1、mac(又称为Hmac)
原理:在md与sha系列算法的基础上加入了密钥,是三大常用的消息摘要算法中最安全的一个。
常用的mac算法:
- HmacMD5
- HmacSHA1
- HmacSHA256
5.2、实现方式
- JDK(缺少二进制字节数组转十六进制的工具,可借助CC或BC的工具类完成)
- Commons Codec(CC,在1.10版本中加入的,其中,产生相应算法密钥的API没有找到,如果有人找到了,请和我讲一下,谢谢)
- Bouncy Castle(BC,比较麻烦,具体参考“慕课网”)
5.2.1、基于JDK实现的Hmac系列算法
package com.util.mac;
import java.io.UnsupportedEncodingException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import javax.crypto.KeyGenerator;
import javax.crypto.Mac;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import org.bouncycastle.util.encoders.Hex;
/**
* 基于JDK的HmacMD5算法
*/
public class HmacMD5JDK {
private static final String ENCODING = "UTF-8";
private static final String ALGORITHM = "HmacMD5";//指定具体算法HmacMD5,HmacSHA1,HmacSHA256
/**
* 产生密钥两种方式 1)是由jdk自己来产生的,2)我们可以自己指定一个字节数组
* 注意:密钥是以二进制字节数组存储的
*/
public static byte[] getKey() throws NoSuchAlgorithmException{
SecretKey key = KeyGenerator.getInstance(ALGORITHM).generateKey();
return key.getEncoded();
}
/**
* HmacMD5加密
* @param data 带加密数据
* @param keyByte 密钥
*/
public static byte[] encode(String data, byte[] keyByte) throws NoSuchAlgorithmException,
InvalidKeyException,
IllegalStateException,
UnsupportedEncodingException {
SecretKey key = new SecretKeySpec(keyByte, ALGORITHM);//还原密钥
Mac mac = Mac.getInstance(key.getAlgorithm());
mac.init(key);//为mac实例初始化密钥
return mac.doFinal(data.getBytes(ENCODING));
}
/**
* HmacMD5加密,并转为16进制
*/
public static String encodeHmacMD5Hex(String data, byte[] keyByte) throws NoSuchAlgorithmException,
UnsupportedEncodingException,
InvalidKeyException,
IllegalStateException {
byte[] encodedByte = encode(data, keyByte);
return new String(Hex.encode(encodedByte));//借助BC
//return new String(org.apache.commons.codec.binary.Hex.encodeHexString(encodedByte));//借助CC
}
/**
* 测试
* @throws IllegalStateException
* @throws InvalidKeyException
*/
public static void main(String[] args) throws UnsupportedEncodingException,
NoSuchAlgorithmException,
InvalidKeyException,
IllegalStateException {
String data = "找一个好姑娘做老婆是我的梦 想!";
/*************测试encode()**************/
System.out.println("原文-->"+data);
byte[] keyByte = HmacMD5JDK.getKey();
byte[] encodedByte = HmacMD5JDK.encode(data, keyByte);
System.out.println("加密后-->"+encodedByte);
byte[] encodedByte2 = HmacMD5JDK.encode(data, keyByte);
System.out.println("加密后-->"+encodedByte2);
for(int i=0;i<encodedByte.length;i++){
System.out.println(encodedByte[i]==encodedByte2[i]);
}
/*************测试encodeHmacMD5Hex()**************/
System.out.println("原文-->"+data);
String encodedStr = HmacMD5JDK.encodeHmacMD5Hex(data, keyByte);
System.out.println("加密后-->"+encodedStr);
String encodedStr2 = HmacMD5JDK.encodeHmacMD5Hex(data, keyByte);
System.out.println("加密后-->"+encodedStr2);
System.out.println(encodedStr.equals(encodedStr2));
}
}
注意几点:
- 产生密钥两种方式:1)直接使用JDK的类(如上边代码所示)2)自己指定字节数组(参考5.2.1)
- 密钥是一个二进制数组,当然为了提高可读性,可以使用Base64加密后,在传递可对方
- 在实际使用中,我们可以将密钥产生后,发送者通过安全途径(线下传递等)传给接收方。
- 在上述的测试中,去测一下同一个消息在使用同一个密钥的情况下,多次mac后结果是否相同。
- 想切换算法,只需要修改ALGORITHM常数即可,当然如果在实际项目中需要用到多种算法,并且需要实现平滑切换,可以采用策略模式,这个以后会再讲。
5.2.1、基于CC实现的Hmac系列算法
package com.util.mac;
import java.io.UnsupportedEncodingException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import org.apache.commons.codec.DecoderException;
import org.apache.commons.codec.binary.Hex;
import org.apache.commons.codec.digest.HmacUtils;
/**
* 基于CC的HmacMD5算法
*/
public class HmacMD5CC {
private static final String ENCODING = "UTF-8";
/**
* 产生密钥
*/
public static byte[] getKey() throws NoSuchAlgorithmException, DecoderException{
return Hex.decodeHex(new char[]{'a','b','c','d'});
}
/**
* HmacMD5加密
* @param data 带加密数据
* @param keyByte 密钥
*/
public static byte[] encode(String data, byte[] keyByte) throws NoSuchAlgorithmException,
InvalidKeyException,
IllegalStateException,
UnsupportedEncodingException {
return HmacUtils.hmacMd5(keyByte, data.getBytes(ENCODING));
}
/**
* HmacMD5加密,并转为16进制
*/
public static String encodeHmacMD5Hex(String data, byte[] keyByte) throws NoSuchAlgorithmException,
UnsupportedEncodingException,
InvalidKeyException,
IllegalStateException {
return HmacUtils.hmacMd5Hex(keyByte, data.getBytes(ENCODING));
}
/**
* 测试
* @throws IllegalStateException
* @throws InvalidKeyException
* @throws DecoderException
*/
public static void main(String[] args) throws UnsupportedEncodingException,
NoSuchAlgorithmException,
InvalidKeyException,
IllegalStateException,
DecoderException {
String data = "找一个好姑娘做老婆是我的梦 想!";
/*************测试encode()**************/
System.out.println("原文-->"+data);
byte[] keyByte = HmacMD5CC.getKey();
byte[] encodedByte = HmacMD5CC.encode(data, keyByte);
System.out.println("加密后-->"+encodedByte);
byte[] encodedByte2 = HmacMD5CC.encode(data, keyByte);
System.out.println("加密后-->"+encodedByte2);
for(int i=0;i<encodedByte.length;i++){
System.out.println(encodedByte[i]==encodedByte2[i]);
}
/*************测试encodeHmacMD5Hex()**************/
System.out.println("原文-->"+data);
String encodedStr = HmacMD5CC.encodeHmacMD5Hex(data, keyByte);
System.out.println("加密后-->"+encodedStr);
String encodedStr2 = HmacMD5CC.encodeHmacMD5Hex(data, keyByte);
System.out.println("加密后-->"+encodedStr2);
System.out.println(encodedStr.equals(encodedStr2));
}
}
注意:
- CC很好的封装了jdk的底层,但是CC是在1.10版本中才添加了hmac系列算法
- 在使用中,若想切换其他算法,只需要调用不同的方法即可,具体的查看本文最下边的CC1.10的API文档链接地址
- 其中,生成密钥在这里是自己指定了一个字节数组,具体的有CC来产生相应算法的密钥的API并没有看到,如果需要,可以自己去封装,当然,如果在CC中有相应的API,请大家和我讲一下,谢谢!
CC API文档:
第五章 消息摘要算法--MAC的更多相关文章
- 第四章 消息摘要算法--SHA
注意:本节内容主要参考自<Java加密与解密的艺术(第2版)>第6章“验证数据完整性--消息摘要算法” 4.1.SHA 原理:消息摘要长度(可以定量为加密后的字符串的长度)越长,安全性越高 ...
- 第三章 消息摘要算法--MD5
注意:本节内容主要参考自<Java加密与解密的艺术(第2版)>第6章“验证数据完整性--消息摘要算法” 3.1.消息摘要算法:防止消息在传递过程中被篡改. 原理:任何消息经过消息摘要算法后 ...
- 消息摘要算法-MAC算法系列
一.简述 mac(Message Authentication Code,消息认证码算法)是含有密钥散列函数算法,兼容了MD和SHA算法的特性,并在此基础上加上了密钥.因此MAC算法也经常被称作HMA ...
- MD、SHA、MAC消息摘要算法实现与应用
1.消息摘要概述 消息摘要(Message Digest)又称为数字摘要(Digital Digest).它是一个唯一对应一个消息或文本的固定长度的值,它由一个单向Hash加密函数对消息进行作用而产生 ...
- 信息加密之消息摘要算法的MAC
MAC是消息摘要算法的第三种实现方式,另外两种方式分别为:MD2\4\5.SHA. MAC的jdk实现:1.默认密钥方式 private static void MAC_JDK(){ try { Ke ...
- MD5 Message Digest Algorithm MD5(中文名为消息摘要算法第五版)
MD5 编辑 Message Digest Algorithm MD5(中文名为消息摘要算法第五版)为计算机安全领域广泛使用的一种散列函数,用以提供消息的完整性保护.该算法的文件号为RFC 1321( ...
- password学4——Java 加密解密之消息摘要算法(MD5 SHA MAC)
Java 加密解密之消息摘要算法(MD5 SHA MAC) 消息摘要 消息摘要(Message Digest)又称为数字摘要(Digital Digest). 它是一个唯一相应一个消息或文本的固定长度 ...
- 一步一步来做WebQQ机器人-(五)(发送消息||完结)
× 本篇主要是: 发送QQ消息(to:好友,群),以及对小黄鸡抓包利用它的语言库 本文是WebQQ流程的最后一章 最后一章内容不多但我还是啰嗦,可能对大部分人都已知晓的流程方法我也会介绍一下 前面几个 ...
- 《Introduction to Tornado》中文翻译计划——第五章:异步Web服务
http://www.pythoner.com/294.html 本文为<Introduction to Tornado>中文翻译,将在https://github.com/alioth3 ...
随机推荐
- 几个经典的css技巧
使用 line-height 垂直居中 line-height:24px; 使用固定宽度的容器并且需要一行垂直居中时,使用 line-height 即可(高度与父层容器一致),更多的垂直居中总结可以看 ...
- 【spring mvc】springmvc在tomcat中的执行过程
一.WEB容器在启动时,它会为每个WEB应用程序都创建一个对应的ServletContext对象(每个web应用程序唯一),它代表当前web应用web容器提供其一个全局的上下文环境,其为后面的spri ...
- go for cryptocurrency
https://blog.conformal.com/category/btcd/ https://github.com/btcsuite/btcd/tree/master/docs https:// ...
- 使用对象作为hashMap的键,需要覆盖hashcode和equals方法
1:HashMap可以存放键值对,如果要以对象(自己创建的类等)作为键,实际上是以对象的散列值(以hashCode方法计算得到)作为键.hashCode计算的hash值默认是对象的地址值. 这样就会忽 ...
- poj2524(简单并查集)
#include <iostream>#include <stdio.h>#include <string.h>#include <stdlib.h>u ...
- [LeetCode] 256. Paint House_Easy tag: Dynamic Programming
There are a row of n houses, each house can be painted with one of the three colors: red, blue or gr ...
- excel 数字转文本
问: 在EXCEL2003中,如何把一列数字转换成文本格式我的意思的,这一列数字全部变成带有文本格式符号(就是左上角有个绿色小三角)的那种以文本形式存储的数字.目前我只知道一个一个双击单元格,但一列数 ...
- zw版【转发·台湾nvp系列Delphi例程】HALCON Roberts2
zw版[转发·台湾nvp系列Delphi例程]HALCON Roberts2 procedure TForm1.Button1Click(Sender: TObject);var op: HOpera ...
- OnClick,OnClientClick和OnServerClick的区别
OnClientClick是客户端事件处理方法,一般采用JavaScript来进行处理,也就是直接在IE端运行,一点击就运行 OnClick是服务器端事件处理方法,在服务器端也就是IIS中运行, ...
- linux常用命令:ping 命令
Linux系统的ping 命令是常用的网络命令,它通常用来测试与目标主机的连通性,我们经常会说“ping一下某机器,看是不是开着”.不能打开网页时会说“你先ping网关地 址192.168.1.1试试 ...