(文章目录)
本文简单的介绍了Base64、消息摘要和其使用示例,并且使用示例以三种不同实现方式及测试 本文介绍三种实现方式,即JDK、apache commons.codec和bouncycastle三种。
一、maven依赖
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<version>6.9.10</version>
</dependency>
<!-- https://mvnrepository.com/artifact/commons-codec/commons-codec -->
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>1.11</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.bouncycastle/bcprov-jdk15on -->
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk15on</artifactId>
<version>1.60</version>
</dependency>
二、Base64
1、概念
内容传送编码是一种以任意8位字节列组合的描述形式,这种形式不容易被人直接识别。 经过base64编码后的数据会比原来数据长约1/3,经过base64编码后的字符串的字符数是以4为单位的整数倍。 实现base64的算法推荐使用apache的common codec类库。
2、应用场景
电子邮件传输、网络数据传输、密钥存储、数字证书存储。
3、示例
1)、JDK示例
1、实现源码
import java.util.Base64;
/**
* @author alan 2018年11月15日 jdk
*/
public class Base64Coder {
/**
* 字符编码
*/
public final static String ENCODING = "UTF-8";
/**
* Base64编码
*
* @param data
* @return
* @throws Exception
*/
public static String encode(String data) throws Exception {
Base64.Encoder encoder = Base64.getEncoder();
byte[] b = data.getBytes(ENCODING);
return encoder.encodeToString(b);
}
/**
* Base64解码
*
* @param data
* @return
* @throws Exception
*/
public static String decode(String data) throws Exception {
Base64.Decoder decoder = Base64.getDecoder();
byte[] b = decoder.decode(data);
return new String(b, ENCODING);
}
}
2、testNG测试
import static org.testng.Assert.assertEquals;
import org.testng.annotations.Test;
/**
* @author alan 2018年11月15日
*/
public class Base64CoderTest {
@Test
public void test() throws Exception {
String inputStr = "Java加密与解密";
// 进行Base64编码
String code = Base64Coder.encode(inputStr);
System.err.println("Base64编码后:\n\t" + code);
// 进行Base64解码
String outputStr = Base64Coder.decode(code);
System.err.println("Base64解码后:\n\t" + outputStr);
// 验证Base64编码解码一致性
assertEquals(inputStr, outputStr);
}
@Test
public void demo() throws Exception {
String str = "Java加密与解密";
// Base64编码
String data = Base64Coder.encode(str);
System.err.println("编码后:\n\t" + data);
// Base64解码
String output = Base64Coder.decode(data);
System.err.println("解码后:\n\t" + output);
}
}
2)、bouncycastle示例
1、实现源码
import org.bouncycastle.util.encoders.Base64;
import org.bouncycastle.util.encoders.UrlBase64;
/**
* @author alan 2018年11月15日
*/
public class Base64Coder {
public final static String ENCODING = "UTF-8";
/**
* Base64编码
*
* @param data 待编码数据
* @return String 编码数据
* @throws Exception
*/
public static String encode(String data) throws Exception {
// 执行编码
byte[] b = Base64.encode(data.getBytes(ENCODING));
return new String(b, ENCODING);
}
/**
* Base64解码
*
* @param data 待解码数据
* @return String 解码数据
* @throws Exception
*/
public static String decode(String data) throws Exception {
// 执行解码
byte[] b = Base64.decode(data.getBytes(ENCODING));
return new String(b, ENCODING);
}
/**
*
* @param data
* @return
* @throws Exception
*/
public static String urlEncode(String data) throws Exception {
// 执行编码
byte[] b = UrlBase64.encode(data.getBytes(ENCODING));
return new String(b, ENCODING);
}
/**
*
* @param data
* @return
* @throws Exception
*/
public static String urlDecode(String data) throws Exception {
// 执行编码
byte[] b = UrlBase64.encode(data.getBytes(ENCODING));
return new String(b, ENCODING);
}
}
2、testNG测试
import static org.testng.Assert.assertEquals;
import org.testng.annotations.Test;
/**
* @author alan 2018年11月15日
*/
public class Base64CoderTest {
@Test
public final void test() throws Exception {
String inputStr = "Java加密与解密";
// 进行Base64编码
String code = Base64Coder.encode(inputStr);
System.err.println("编码后:\t" + code);
// 进行Base64解码
String outputStr = Base64Coder.decode(code);
System.err.println("解码后:\t" + outputStr);
// 验证Base64编码解码一致性
assertEquals(inputStr, outputStr);
}
@Test
public final void demo() throws Exception {
String str = "Base64 编码";
// Base64编码
String data = Base64Coder.encode(str);
System.err.println("编码后:\t" + new String(data));
// Base64解码
String output = Base64Coder.decode(data);
System.err.println("解码后:\t" + new String(output));
}
@Test
public final void demo2() throws Exception {
String str = "Base64 编码";
// Url Base64编码
String data = Base64Coder.urlEncode(str);
System.err.println("编码后:\t" + new String(data));
// Url Base64解码
String output = Base64Coder.urlDecode(data);
System.err.println("解码后:\t" + new String(output));
}
}
3)、apache commons示例
1、实现源码
import org.apache.commons.codec.binary.Base64;
/**
* @author alan 2018年11月15日
*/
public class Base64Coder {
public final static String ENCODING = "UTF-8";
/**
* Base64编码
*
* @param data 待编码数据
* @return String 编码数据
* @throws Exception
*/
public static String encode(String data) throws Exception {
// 执行编码
byte[] b = Base64.encodeBase64(data.getBytes(ENCODING));
return new String(b, ENCODING);
}
/**
* Base64安全编码<br>
* 遵循RFC 2045实现
*
* @param data 待编码数据
* @return String 编码数据
*
* @throws Exception
*/
public static String encodeSafe(String data) throws Exception {
// 执行编码
byte[] b = Base64.encodeBase64(data.getBytes(ENCODING), true);
return new String(b, ENCODING);
}
/**
* Base64解码
*
* @param data 待解码数据
* @return String 解码数据
* @throws Exception
*/
public static String decode(String data) throws Exception {
// 执行解码
byte[] b = Base64.decodeBase64(data.getBytes(ENCODING));
return new String(b, ENCODING);
}
}
2、testNG测试
import static org.testng.Assert.assertEquals;
import org.apache.commons.codec.binary.Base64;
import org.testng.annotations.Test;
/**
* @author alan 2018年11月15日
*/
public class Base64CoderTest {
@Test
public final void test() throws Exception {
String inputStr = "Java加密与解密";
// 进行Base64编码
String code = Base64Coder.encode(inputStr);
System.err.println("编码后:\t" + code);
// 进行Base64解码
String outputStr = Base64Coder.decode(code);
System.err.println("解码后:\t" + outputStr);
// 验证Base64编码解码一致性
assertEquals(inputStr, outputStr);
}
@Test
public final void testSafe() throws Exception {
String inputStr = "Java加密与解密";
// 进行Base64编码
String code = Base64Coder.encodeSafe(inputStr);
System.err.println("编码后:\t" + code);
// 进行Base64解码
String outputStr = Base64Coder.decode(code);
System.err.println("解码后:\t" + outputStr);
// 验证Base64编码解码一致性
assertEquals(inputStr, outputStr);
}
@Test
public final void demo() throws Exception {
String str = "Base64 编码1";
// Base64编码
String data = Base64Coder.encode(str);
System.err.println("编码后:\t" + new String(data));
// Base64解码
String output = Base64Coder.decode(data);
System.err.println("解码后:\t" + new String(output));
}
@Test
public final void demo2() throws Exception {
String str = "Base64 编码2";
byte[] input = str.getBytes();
// Base64编码
byte[] data = Base64.encodeBase64(input);
System.err.println("编码后:\t" + new String(data));
// Base64解码
byte[] output = Base64.decodeBase64(data);
System.err.println("解码后:\t" + new String(output));
}
@Test
public final void demo3() throws Exception {
String str = "Base64 编码3";
// Base64编码
String data = Base64Coder.encodeSafe(str);
System.err.println("编码后:\t" + new String(data));
// Base64解码
byte[] output = Base64.decodeBase64(data);
System.err.println("解码后:\t" + new String(output));
}
}
三、消息摘要(message digest MD)
1、介绍
任何消息经过散列函数处理后都会获得唯一的散列值(hashcode),该过程称为消息摘要,其散列值成为数字指纹,其算法即是消息摘要算法。
消息摘要算法又称为散列算法,其核心在于散列函数的单向性,即通过散列函数可获得对应的散列值,但不可通过该散列值获得其原始信息。
消息摘要算法包含三大系列,即MD 、SHA 和MC,常用于验证数据的完整性,是数字签名的核心算法。
- MD,message digest,消息摘要算法,包括MD2、MD4、MD5
- SHA,secure hash algorithm,安全散列算法,包括SHA-224、SHA-256、SHA-384、SHA-512
- MAC,message authentication code,消息认证码算法,综合了MD和SHA算法,包括HmacMD5、HmacSHA1、HmacSHA256、HmacSHA384、HmacSHA512
2、MD
1)、介绍
MD5是由MD2、MD3、MD4改进而来,是典型的消息摘要算法。MD5算法对输入任意长度的消息进行运行,产生一个128位的消息摘要。如果将这个128位的信息摘要信息换算成十六进制,则可以得到一个32位的字符串(32位的数字字母混合码)。
2)、应用场景
MD5之后的推荐替代应该是SHA,已经不适合安全性要求较高的场景。
3)、示例
1、jdk示例
- 实现源码
import java.security.MessageDigest;
/**
* @author alan 2018年11月15日 jdk
*/
public class MDCoder {
public static byte[] encodeMD2(byte[] data) throws Exception {
// 初始化MessageDigest
MessageDigest md = MessageDigest.getInstance("MD2");
// 执行消息摘要
return md.digest(data);
}
public static byte[] encodeMD5(byte[] data) throws Exception {
// 初始化MessageDigest
MessageDigest md = MessageDigest.getInstance("MD5");
// 执行消息摘要
return md.digest(data);
}
}
- testNG测试
import static org.testng.Assert.assertEquals;
import org.testng.annotations.Test;
/**
* @author alan 2018年11月15日
*/
public class MDCoderTest {
@Test
public final void testEncodeMD2() throws Exception {
String str = "MD2消息摘要";
// 获得摘要信息
byte[] data1 = MDCoder.encodeMD2(str.getBytes());
byte[] data2 = MDCoder.encodeMD2(str.getBytes());
// 校验
assertEquals(data1, data2);
}
@Test
public final void testEncodeMD5() throws Exception {
String str = "MD5消息摘要";
// 获得摘要信息
byte[] data1 = MDCoder.encodeMD5(str.getBytes());
byte[] data2 = MDCoder.encodeMD5(str.getBytes());
// 校验
assertEquals(data1, data2);
}
}
2、bouncycastle示例
- 实现源码
import java.security.MessageDigest;
import java.security.Security;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.util.encoders.Hex;
/**
* @author alan 2018年11月15日
*/
public class MD4Coder {
public static byte[] encodeMD4(byte[] data) throws Exception {
// 加入BouncyCastleProvider支持
Security.addProvider(new BouncyCastleProvider());
// 初始化MessageDigest
MessageDigest md = MessageDigest.getInstance("MD4");
// 执行消息摘要
return md.digest(data);
}
public static String encodeMD4Hex(byte[] data) throws Exception {
// 执行消息摘要
byte[] b = encodeMD4(data);
// 做十六进制编码处理
return new String(Hex.encode(b));
}
}
- testNG测试
import static org.testng.Assert.assertEquals;
import org.testng.annotations.Test;
/**
* @author alan 2018年11月15日
*/
public class MD4CoderTest {
@Test
public final void testEncodeMD4() throws Exception {
String str = "MD4消息摘要";
// 获得摘要信息
byte[] data1 = MD4Coder.encodeMD4(str.getBytes());
byte[] data2 = MD4Coder.encodeMD4(str.getBytes());
// 校验
assertEquals(data1, data2);
}
@Test
public final void testEncodeMD4Hex() throws Exception {
String str = "MD4Hex消息摘要";
// 获得摘要信息
String data1 = MD4Coder.encodeMD4Hex(str.getBytes());
String data2 = MD4Coder.encodeMD4Hex(str.getBytes());
System.err.println("原文:\t" + str);
System.err.println("MD4Hex-1:\t" + data1);
System.err.println("MD4Hex-2:\t" + data2);
// 校验
assertEquals(data1, data2);
}
}
3、apache commons示例
- 实现源码
import org.apache.commons.codec.digest.DigestUtils;
/**
* @author alan 2018年11月15日
*/
public class MD5Coder {
public static byte[] encodeMD5(String data) throws Exception {
// 执行消息摘要
return DigestUtils.md5(data);
}
public static String encodeMD5Hex(String data) throws Exception {
// 执行消息摘要
return DigestUtils.md5Hex(data);
}
}
- testNG测试
import static org.testng.Assert.assertEquals;
import org.testng.annotations.Test;
/**
* @author alan 2018年11月15日
*/
public class MD5CoderTest {
@Test
public final void testEncodeMD5() throws Exception {
String str = "MD5消息摘要";
// 获得摘要信息
byte[] data1 = MD5Coder.encodeMD5(str);
byte[] data2 = MD5Coder.encodeMD5(str);
// 校验
assertEquals(data1, data2);
}
@Test
public final void testEncodeMD5Hex() throws Exception {
String str = "MD5Hex消息摘要";
// 获得摘要信息
String data1 = MD5Coder.encodeMD5Hex(str);
String data2 = MD5Coder.encodeMD5Hex(str);
System.err.println("原文:\t" + str);
System.err.println("MD5Hex-1:\t" + data1);
System.err.println("MD5Hex-2:\t" + data2);
// 校验
assertEquals(data1, data2);
}
}
3、SHA
1)、介绍
SHA算法是基于MD4算法的,已经成为消息摘要的首选,与MD不同的是其摘要更长,安全性更高。 SHA算法有SHA-1、SHA-224、SHA-256、SHA-384、SHA-512,除了SHA-1外,其他都是根据信息摘要的长度命名的。SHA-224是为了符合3DES的需要而定义的。
2)、应用场景
需要报文摘要功能,且安全要求比较高的应用场景,目前很多数字签名都是使用SHA的算法。
3)、示例
SHA-224是由BouncyCastleProvider实现,jdk本身没有实现。
1、jdk示例
- 实现源码
import java.security.MessageDigest;
/**
* @author alan 2018年11月15日
*/
public class SHACoder {
/**
* SHA-1加密
*/
public static byte[] encodeSHA(byte[] data) throws Exception {
// 初始化MessageDigest
MessageDigest md = MessageDigest.getInstance("SHA");
// 执行消息摘要
return md.digest(data);
}
/**
* SHA-256加密
*/
public static byte[] encodeSHA256(byte[] data) throws Exception {
// 初始化MessageDigest
MessageDigest md = MessageDigest.getInstance("SHA-256");
// 执行消息摘要
return md.digest(data);
}
/**
* SHA-384加密
*/
public static byte[] encodeSHA384(byte[] data) throws Exception {
// 初始化MessageDigest
MessageDigest md = MessageDigest.getInstance("SHA-384");
// 执行消息摘要
return md.digest(data);
}
/**
* SHA-512加密
*/
public static byte[] encodeSHA512(byte[] data) throws Exception {
// 初始化MessageDigest
MessageDigest md = MessageDigest.getInstance("SHA-512");
// 执行消息摘要
return md.digest(data);
}
}
- testNG测试
import static org.testng.Assert.assertEquals;
import org.testng.annotations.Test;
/**
* @author alan 2018年11月15日
*/
public class SHACoderTest {
@Test
public final void testEncodeSHA() throws Exception {
String str = "SHA1消息摘要";
// 获得摘要信息
byte[] data1 = SHACoder.encodeSHA(str.getBytes());
byte[] data2 = SHACoder.encodeSHA(str.getBytes());
// 校验
assertEquals(data1, data2);
}
@Test
public final void testEncodeSHA256() throws Exception {
String str = "SHA256消息摘要";
// 获得摘要信息
byte[] data1 = SHACoder.encodeSHA256(str.getBytes());
byte[] data2 = SHACoder.encodeSHA256(str.getBytes());
// 校验
assertEquals(data1, data2);
}
@Test
public final void testEncodeSHA384() throws Exception {
String str = "SHA384消息摘要";
// 获得摘要信息
byte[] data1 = SHACoder.encodeSHA384(str.getBytes());
byte[] data2 = SHACoder.encodeSHA384(str.getBytes());
// 校验
assertEquals(data1, data2);
}
@Test
public final void testEncodeSHA512() throws Exception {
String str = "SHA512消息摘要";
// 获得摘要信息
byte[] data1 = SHACoder.encodeSHA512(str.getBytes());
byte[] data2 = SHACoder.encodeSHA512(str.getBytes());
// 校验
assertEquals(data1, data2);
}
}
2、bouncycastle示例
- 实现源码
import java.security.MessageDigest;
import java.security.Security;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.util.encoders.Hex;
/**
* @author alan 2018年11月15日
*/
public class SHA224Coder {
public static byte[] encodeSHA224(byte[] data) throws Exception {
// 加入BouncyCastleProvider支持
Security.addProvider(new BouncyCastleProvider());
// 初始化MessageDigest
MessageDigest md = MessageDigest.getInstance("SHA-224");
// 执行消息摘要
return md.digest(data);
}
public static String encodeSHA224Hex(byte[] data) throws Exception {
// 执行消息摘要
byte[] b = encodeSHA224(data);
// 做十六进制编码处理
return new String(Hex.encode(b));
}
}
- testNG测试
import static org.testng.Assert.assertEquals;
import org.testng.annotations.Test;
/**
* @author alan
* 2018年11月15日
*/
public class SHA224CoderTest {
@Test
public final void testEncodeSHA224() throws Exception {
String str = "SHA224消息摘要";
// 获得摘要信息
byte[] data1 = SHA224Coder.encodeSHA224(str.getBytes());
byte[] data2 = SHA224Coder.encodeSHA224(str.getBytes());
// 校验
assertEquals(data1, data2);
}
@Test
public final void testEncodeSHA224Hex() throws Exception {
String str = "SHA224Hex消息摘要";
// 获得摘要信息
String data1 = SHA224Coder.encodeSHA224Hex(str.getBytes());
String data2 = SHA224Coder.encodeSHA224Hex(str.getBytes());
System.err.println("原文:\t" + str);
System.err.println("SHA224Hex-1:\t" + data1);
System.err.println("SHA224Hex-2:\t" + data2);
// 校验
assertEquals(data1, data2);
}
}
3、apache commons示例
- 实现源码
import org.apache.commons.codec.digest.DigestUtils;
/**
* @author alan
* 2018年11月15日
*/
public class SHACoder {
/**
* SHA1加密
*/
public static byte[] encodeSHA(String data) throws Exception {
// 执行消息摘要
return DigestUtils.sha(data);
}
/**
* SHA1Hex加密
*/
public static String encodeSHAHex(String data) throws Exception {
// 执行消息摘要
return DigestUtils.shaHex(data);
}
/**
* SHA256加密
*/
public static byte[] encodeSHA256(String data) throws Exception {
// 执行消息摘要
return DigestUtils.sha256(data);
}
/**
* SHA256Hex加密
*/
public static String encodeSHA256Hex(String data) throws Exception {
// 执行消息摘要
return DigestUtils.sha256Hex(data);
}
/**
* SHA384加密
*/
public static byte[] encodeSHA384(String data) throws Exception {
// 执行消息摘要
return DigestUtils.sha384(data);
}
/**
* SHA384Hex加密
*/
public static String encodeSHA384Hex(String data) throws Exception {
// 执行消息摘要
return DigestUtils.sha384Hex(data);
}
/**
* SHA512Hex加密
*/
public static byte[] encodeSHA512(String data) throws Exception {
// 执行消息摘要
return DigestUtils.sha512(data);
}
/**
* SHA512Hex加密
*/
public static String encodeSHA512Hex(String data) throws Exception {
// 执行消息摘要
return DigestUtils.sha512Hex(data);
}
}
- testNG测试
import static org.testng.Assert.assertEquals;
import org.testng.annotations.Test;
/**
* @author alan 2018年11月15日
*/
public class SHACoderTest {
/**
* 测试SHA-1
*/
@Test
public final void testEncodeSHA() throws Exception {
String str = "SHA1消息摘要";
// 获得摘要信息
byte[] data1 = SHACoder.encodeSHA(str);
byte[] data2 = SHACoder.encodeSHA(str);
// 校验
assertEquals(data1, data2);
}
/**
* 测试SHA-1Hex
*/
@Test
public final void testEncodeSHAHex() throws Exception {
String str = "SHA-1Hex消息摘要";
// 获得摘要信息
String data1 = SHACoder.encodeSHAHex(str);
String data2 = SHACoder.encodeSHAHex(str);
System.err.println("原文:\t" + str);
System.err.println("SHA1Hex-1:\t" + data1);
System.err.println("SHA1Hex-2:\t" + data2);
// 校验
assertEquals(data1, data2);
}
/**
* 测试SHA-256
*/
@Test
public final void testEncodeSHA256() throws Exception {
String str = "SHA256消息摘要";
// 获得摘要信息
byte[] data1 = SHACoder.encodeSHA256(str);
byte[] data2 = SHACoder.encodeSHA256(str);
// 校验
assertEquals(data1, data2);
}
/**
* 测试SHA-256Hex
*/
@Test
public final void testEncodeSHA256Hex() throws Exception {
String str = "SHA256Hex消息摘要";
// 获得摘要信息
String data1 = SHACoder.encodeSHA256Hex(str);
String data2 = SHACoder.encodeSHA256Hex(str);
System.err.println("原文:\t" + str);
System.err.println("SHA256Hex-1:\t" + data1);
System.err.println("SHA256Hex-2:\t" + data2);
// 校验
assertEquals(data1, data2);
}
/**
* 测试SHA-384
*/
@Test
public final void testEncodeSHA384() throws Exception {
String str = "SHA384消息摘要";
// 获得摘要信息
byte[] data1 = SHACoder.encodeSHA384(str);
byte[] data2 = SHACoder.encodeSHA384(str);
// 校验
assertEquals(data1, data2);
}
/**
* 测试SHA-384Hex
*/
@Test
public final void testEncodeSHA384Hex() throws Exception {
String str = "SHA384Hex消息摘要";
// 获得摘要信息
String data1 = SHACoder.encodeSHA384Hex(str);
String data2 = SHACoder.encodeSHA384Hex(str);
System.err.println("原文:\t" + str);
System.err.println("SHA384Hex-1:\t" + data1);
System.err.println("SHA384Hex-2:\t" + data2);
// 校验
assertEquals(data1, data2);
}
/**
* 测试SHA-512
*/
@Test
public final void testEncodeSHA512() throws Exception {
String str = "SHA512消息摘要";
// 获得摘要信息
byte[] data1 = SHACoder.encodeSHA512(str);
byte[] data2 = SHACoder.encodeSHA512(str);
// 校验
assertEquals(data1, data2);
}
/**
* 测试SHA-512Hex
*/
@Test
public final void testEncodeSHA512Hex() throws Exception {
String str = "SHA512Hex消息摘要";
// 获得摘要信息
String data1 = SHACoder.encodeSHA512Hex(str);
String data2 = SHACoder.encodeSHA512Hex(str);
System.err.println("原文:\t" + str);
System.err.println("SHA512Hex-1:\t" + data1);
System.err.println("SHA512Hex-2:\t" + data2);
// 校验
assertEquals(data1, data2);
}
}
4、MAC
1)、定义
MAC是含有密钥散列函数算法,包含了MD和SHA的特性,并在此基础上加入了密钥,通常也会把MAC成为HMAC(keyed-Hash Message Authentication Code)。MAC算法集合了MD和SHA两大系列消息摘要算法,MD系列有HmacMD2、HmacMD4、HmacMD5,SHA系列有HmacSHA1、HmacSHA224、HmacSHA256、HmacSHA384、HmacSHA512。 经MAC算法得到的摘要值可以使用十六进制编码表示,其摘要值长度与参与实现的算法摘要值长度相同,比如HmacSHA1算法得到的摘要长度就是SHA1算法得到摘要长度,都是160位二进制数,换算成十六进制编码为40位。
2)、应用场景
在MD和SHA均不满足使用场景要求的时候,MAC是一个有效的补充。
3)、示例
1、jdk示例
- 实现源码
import javax.crypto.KeyGenerator;
import javax.crypto.Mac;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
/**
* @author alan 2018年11月15日
*/
public class MACCoder {
/**
* 初始化HmacMD5密钥
*
* @return
* @throws Exception
*/
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[] 消息摘要
*
* @throws Exception
*/
public static byte[] encodeHmacMD5(byte[] data, byte[] key) throws Exception {
// 还原密钥
SecretKey secretKey = new SecretKeySpec(key, "HmacMD5");
// 实例化Mac "SslMacMD5"
Mac mac = Mac.getInstance("SslMacMD5");// secretKey.getAlgorithm());
// 初始化Mac
mac.init(secretKey);
// 执行消息摘要
return mac.doFinal(data);
}
/**
* 初始化HmacSHA1密钥
*
* @return
* @throws Exception
*/
public static byte[] initHmacSHAKey() throws Exception {
// 初始化KeyGenerator
KeyGenerator keyGenerator = KeyGenerator.getInstance("HMacTiger");
// 产生秘密密钥
SecretKey secretKey = keyGenerator.generateKey();
// 获得密钥
return secretKey.getEncoded();
}
/**
* HmacSHA1加密
*
* @param data
* 待加密数据
* @param key
* 密钥
* @return byte[] 消息摘要
*
* @throws Exception
*/
public static byte[] encodeHmacSHA(byte[] data, byte[] key) throws Exception {
// 还原密钥
SecretKey secretKey = new SecretKeySpec(key, "HMacTiger");
// 实例化Mac SslMacMD5
Mac mac = Mac.getInstance("SslMacMD5");// secretKey.getAlgorithm());
// 初始化Mac
mac.init(secretKey);
// 执行消息摘要
return mac.doFinal(data);
}
// // 根据所安装的 JCE 仲裁策略文件,返回指定转换的最大密钥长度。
// public final static int getMaxAllowedKeyLength(String transformation)
/**
* 初始化HmacSHA256密钥
*
* @return
* @throws Exception
*/
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[] 消息摘要
*
* @throws Exception
*/
public static byte[] encodeHmacSHA256(byte[] data, byte[] key) throws Exception {
// 还原密钥
SecretKey secretKey = new SecretKeySpec(key, "HmacSHA256");
// 实例化Mac
Mac mac = Mac.getInstance(secretKey.getAlgorithm());
// 初始化Mac
mac.init(secretKey);
// 执行消息摘要
return mac.doFinal(data);
}
/**
* 初始化HmacSHA384密钥
*
* @return
* @throws Exception
*/
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[] 消息摘要
*
* @throws Exception
*/
public static byte[] encodeHmacSHA384(byte[] data, byte[] key) throws Exception {
// 还原密钥
SecretKey secretKey = new SecretKeySpec(key, "HmacSHA384");
// 实例化Mac
Mac mac = Mac.getInstance(secretKey.getAlgorithm());
// 初始化Mac
mac.init(secretKey);
// 执行消息摘要
return mac.doFinal(data);
}
/**
* 初始化HmacSHA512密钥
*
* @return
* @throws Exception
*/
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[] 消息摘要
*
* @throws Exception
*/
public static byte[] encodeHmacSHA512(byte[] data, byte[] key) throws Exception {
// 还原密钥
SecretKey secretKey = new SecretKeySpec(key, "HmacSHA512");
// 实例化Mac
Mac mac = Mac.getInstance(secretKey.getAlgorithm());
// 初始化Mac
mac.init(secretKey);
// 执行消息摘要
return mac.doFinal(data);
}
}
- testNG测试
import static org.testng.Assert.assertEquals;
import org.testng.annotations.Test;
/**
* @author alan 2018年11月15日
*/
public class MACCoderTest {
/**
* 测试HmacMD5
*/
@Test
public final void testEncodeHmacMD5() throws Exception {
String str = "HmacMD5消息摘要";
// 初始化密钥
byte[] key = MACCoder.initHmacMD5Key();
// 获得摘要信息
byte[] data1 = MACCoder.encodeHmacMD5(str.getBytes(), key);
byte[] data2 = MACCoder.encodeHmacMD5(str.getBytes(), key);
// 校验
assertEquals(data1, data2);
}
/**
* 测试HmacSHA1
*/
@Test
public final void testEncodeHmacSHA() throws Exception {
String str = "HmacSHA1消息摘要";
// 初始化密钥
byte[] key = MACCoder.initHmacSHAKey();
// 获得摘要信息
byte[] data1 = MACCoder.encodeHmacSHA(str.getBytes(), key);
byte[] data2 = MACCoder.encodeHmacSHA(str.getBytes(), key);
// 校验
assertEquals(data1, data2);
}
/**
* 测试HmacSHA256
*/
@Test
public final void testEncodeHmacSHA256() throws Exception {
String str = "HmacSHA256消息摘要";
// 初始化密钥
byte[] key = MACCoder.initHmacSHA256Key();
// 获得摘要信息
byte[] data1 = MACCoder.encodeHmacSHA256(str.getBytes(), key);
byte[] data2 = MACCoder.encodeHmacSHA256(str.getBytes(), key);
// 校验
assertEquals(data1, data2);
}
/**
* 测试HmacSHA384
*/
@Test
public final void testEncodeHmacSHA384() throws Exception {
String str = "HmacSHA384消息摘要";
// 初始化密钥
byte[] key = MACCoder.initHmacSHA384Key();
// 获得摘要信息
byte[] data1 = MACCoder.encodeHmacSHA384(str.getBytes(), key);
byte[] data2 = MACCoder.encodeHmacSHA384(str.getBytes(), key);
// 校验
assertEquals(data1, data2);
}
/**
* 测试HmacSHA512
*/
@Test
public final void testEncodeHmacSHA512() throws Exception {
String str = "HmacSHA512消息摘要";
// 初始化密钥
byte[] key = MACCoder.initHmacSHA512Key();
// 获得摘要信息
byte[] data1 = MACCoder.encodeHmacSHA512(str.getBytes(), key);
byte[] data2 = MACCoder.encodeHmacSHA512(str.getBytes(), key);
// 校验
assertEquals(data1, data2);
}
}
2、bouncycastle示例
- 实现源码
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;
/**
* @author alan 2018年11月15日
*/
public class MACCoder {
/**
* 初始化HmacMD2密钥
*/
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 byte[]
* 密钥
* @return byte[] 消息摘要
* @throws Exception
*/
public static byte[] encodeHmacMD2(byte[] data, byte[] key) throws Exception {
// 加入BouncyCastleProvider支持
Security.addProvider(new BouncyCastleProvider());
// 还原密钥
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[] 消息摘要
* @throws Exception
*/
public static String encodeHmacMD2Hex(byte[] data, byte[] key) throws Exception {
// 执行消息摘要
byte[] b = encodeHmacMD2(data, key);
// 做十六进制转换
return new String(Hex.encode(b));
}
/**
* 初始化HmacMD4密钥
*
* @return byte[] 密钥
* @throws Exception
*/
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 byte[]
* 密钥
* @return byte[] 消息摘要
* @throws Exception
*/
public static byte[] encodeHmacMD4(byte[] data, byte[] key) throws Exception {
// 加入BouncyCastleProvider支持
Security.addProvider(new BouncyCastleProvider());
// 还原密钥
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 byte[]
* 密钥
* @return String 消息摘要
* @throws Exception
*/
public static String encodeHmacMD4Hex(byte[] data, byte[] key) throws Exception {
// 执行消息摘要
byte[] b = encodeHmacMD4(data, key);
// 做十六进制转换
return new String(Hex.encode(b));
}
/**
* 初始化HmacSHA224密钥
*
* @return byte[] 密钥
* @throws Exception
*/
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 byte[]
* 密钥
* @return byte[] 消息摘要
* @throws Exception
*/
public static byte[] encodeHmacSHA224(byte[] data, byte[] key) throws Exception {
// 加入BouncyCastleProvider支持
Security.addProvider(new BouncyCastleProvider());
// 还原密钥
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 byte[]
* 密钥
* @return String 消息摘要
* @throws Exception
*/
public static String encodeHmacSHA224Hex(byte[] data, byte[] key) throws Exception {
// 执行消息摘要
byte[] b = encodeHmacSHA224(data, key);
// 做十六进制转换
return new String(Hex.encode(b));
}
}
- testNG测试
import static org.testng.Assert.assertEquals;
import org.testng.annotations.Test;
/**
* @author alan 2018年11月15日
*/
public class MACCoderTest {
@Test
public final void testEncodeHmacMD2() throws Exception {
String str = "HmacMD2消息摘要";
// 初始化密钥
byte[] key = MACCoder.initHmacMD2Key();
// 获得摘要信息
byte[] data1 = MACCoder.encodeHmacMD2(str.getBytes(), key);
byte[] data2 = MACCoder.encodeHmacMD2(str.getBytes(), key);
// 校验
assertEquals(data1, data2);
}
/**
* 测试HmacMD2Hex
*
* @throws Exception
*/
@Test
public final void testEncodeHmacMD2Hex() throws Exception {
String str = "HmacMD2Hex消息摘要";
// 初始化密钥
byte[] key = MACCoder.initHmacMD2Key();
// 获得摘要信息
String data1 = MACCoder.encodeHmacMD2Hex(str.getBytes(), key);
String data2 = MACCoder.encodeHmacMD2Hex(str.getBytes(), key);
System.err.println("原文:\t" + str);
System.err.println("HmacMD2Hex-1:\t" + data1);
System.err.println("HmacMD2Hex-2:\t" + data2);
// 校验
assertEquals(data1, data2);
}
/**
* 测试HmacMD4
*
* @throws Exception
*/
@Test
public final void testEncodeHmacMD4() throws Exception {
String str = "HmacMD4消息摘要";
// 初始化密钥
byte[] key = MACCoder.initHmacMD4Key();
// 获得摘要信息
byte[] data1 = MACCoder.encodeHmacMD4(str.getBytes(), key);
byte[] data2 = MACCoder.encodeHmacMD4(str.getBytes(), key);
// 校验
assertEquals(data1, data2);
}
/**
* 测试HmacMD4Hex
*
* @throws Exception
*/
@Test
public final void testEncodeHmacMD4Hex() throws Exception {
String str = "HmacMD4Hex消息摘要";
// 初始化密钥
byte[] key = MACCoder.initHmacMD4Key();
// 获得摘要信息
String data1 = MACCoder.encodeHmacMD4Hex(str.getBytes(), key);
String data2 = MACCoder.encodeHmacMD4Hex(str.getBytes(), key);
System.err.println("原文:\t" + str);
System.err.println("HmacMD4Hex-1:\t" + data1);
System.err.println("HmacMD4Hex-2:\t" + data2);
// 校验
assertEquals(data1, data2);
}
/**
* 测试HmacSHA224
*
* @throws Exception
*/
@Test
public final void testEncodeHmacSHA224() throws Exception {
String str = "HmacSHA224消息摘要";
// 初始化密钥
byte[] key = MACCoder.initHmacSHA224Key();
// 获得摘要信息
byte[] data1 = MACCoder.encodeHmacSHA224(str.getBytes(), key);
byte[] data2 = MACCoder.encodeHmacSHA224(str.getBytes(), key);
// 校验
assertEquals(data1, data2);
}
/**
* 测试HmacSHA224Hex
*
* @throws Exception
*/
@Test
public final void testEncodeHmacSHA224Hex() throws Exception {
String str = "HmacSHA224Hex消息摘要";
// 初始化密钥
byte[] key = MACCoder.initHmacSHA224Key();
// 获得摘要信息
String data1 = MACCoder.encodeHmacSHA224Hex(str.getBytes(), key);
String data2 = MACCoder.encodeHmacSHA224Hex(str.getBytes(), key);
System.err.println("原文:\t" + str);
System.err.println("HmacSHA224Hex-1:\t" + data1);
System.err.println("HmacSHA224Hex-2:\t" + data2);
// 校验
assertEquals(data1, data2);
}
}
3、apache commons示例
- 实现源码
在这里插入代码片
- testNG测试
在这里插入代码片
以上,简单的介绍了Base64、消息摘要和其使用示例,并且使用示例以三种不同实现方式及测试。
标签:MD,Exception,String,示例,public,数据安全,byte,data,throws From: https://blog.51cto.com/alanchan2win/6522464