一、概述
MAC算法结合了MD5和SHA算法的优势,并加入密钥的支持,是一种更为安全的消息摘要算法。
MAC(Message Authentication Code,消息认证码算法)是含有密钥的散列函数算法,兼容了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位。
二、实现和应用
1、Sun的实现和应用
在java6中,MAC系列算法需要通过Mac类提供支持。java6中仅仅提供HmacMD5、HmacSHA1、HmacSHA256、HmacSHA384和HmacSHA512四种算法。
Mac算法是带有密钥的消息摘要算法,所以实现起来要分为两步:
1)、构建密钥
2)、执行消息摘要
[java] view plaincopyprint?
1. package com.tao.test;
2.
3. import java.security.NoSuchAlgorithmException;
4.
5. import javax.crypto.KeyGenerator;
6. import javax.crypto.Mac;
7. import javax.crypto.SecretKey;
8. import javax.crypto.spec.SecretKeySpec;
9. import javax.xml.bind.annotation.adapters.HexBinaryAdapter;
10.
11. /**
12. * MAC算法工具类
13. * 对于HmacMD5、HmacSHA1、HmacSHA256、HmacSHA384、HmacSHA512应用的步骤都是一模一样的。具体看下面的代码
14. */
15. class MACCoder {
16. /**
17. * 产生HmacMD5摘要算法的密钥
18. */
19. public static byte[] initHmacMD5Key() throws NoSuchAlgorithmException {
20. // 初始化HmacMD5摘要算法的密钥产生器
21. KeyGenerator generator = KeyGenerator.getInstance("HmacMD5");
22. // 产生密钥
23. SecretKey secretKey = generator.generateKey();
24. // 获得密钥
25. byte[] key = secretKey.getEncoded();
26. return key;
27. }
28.
29. /**
30. * HmacMd5摘要算法
31. * 对于给定生成的不同密钥,得到的摘要消息会不同,所以在实际应用中,要保存我们的密钥
32. */
33. public static String encodeHmacMD5(byte[] data, byte[] key) throws Exception {
34. // 还原密钥
35. SecretKey secretKey = new SecretKeySpec(key, "HmacMD5");
36. // 实例化Mac
37. Mac mac = Mac.getInstance(secretKey.getAlgorithm());
38. //初始化mac
39. mac.init(secretKey);
40. //执行消息摘要
41. byte[] digest = mac.doFinal(data);
42. return new HexBinaryAdapter().marshal(digest);//转为十六进制的字符串
43. }
44.
45.
46. /**
47. * 产生HmacSHA1摘要算法的密钥www.2cto.com
48. */
49. public static byte[] initHmacSHAKey() throws NoSuchAlgorithmException {
50. // 初始化HmacMD5摘要算法的密钥产生器
51. KeyGenerator generator = KeyGenerator.getInstance("HmacSHA1");
52. // 产生密钥
53. SecretKey secretKey = generator.generateKey();
54. // 获得密钥
55. byte[] key = secretKey.getEncoded();
56. return key;
57. }
58.
59. /**
60. * HmacSHA1摘要算法
61. * 对于给定生成的不同密钥,得到的摘要消息会不同,所以在实际应用中,要保存我们的密钥
62. */
63. public static String encodeHmacSHA(byte[] data, byte[] key) throws Exception {
64. // 还原密钥
65. SecretKey secretKey = new SecretKeySpec(key, "HmacSHA1");
66. // 实例化Mac
67. Mac mac = Mac.getInstance(secretKey.getAlgorithm());
68. //初始化mac
69. mac.init(secretKey);
70. //执行消息摘要
71. byte[] digest = mac.doFinal(data);
72. return new HexBinaryAdapter().marshal(digest);//转为十六进制的字符串
73. }
74.
75.
76.
77. /**
78. * 产生HmacSHA256摘要算法的密钥
79. */
80. public static byte[] initHmacSHA256Key() throws NoSuchAlgorithmException {
81. // 初始化HmacMD5摘要算法的密钥产生器
82. KeyGenerator generator = KeyGenerator.getInstance("HmacSHA256");
83. // 产生密钥
84. SecretKey secretKey = generator.generateKey();
85. // 获得密钥
86. byte[] key = secretKey.getEncoded();
87. return key;
88. }
89.
90. /**
91. * HmacSHA1摘要算法
92. * 对于给定生成的不同密钥,得到的摘要消息会不同,所以在实际应用中,要保存我们的密钥
93. */
94. public static String encodeHmacSHA256(byte[] data, byte[] key) throws Exception {
95. // 还原密钥
96. SecretKey secretKey = new SecretKeySpec(key, "HmacSHA256");
97. // 实例化Mac
98. Mac mac = Mac.getInstance(secretKey.getAlgorithm());
99. //初始化mac
100. mac.init(secretKey);
101. //执行消息摘要
102. byte[] digest = mac.doFinal(data);
103. return new HexBinaryAdapter().marshal(digest);//转为十六进制的字符串
104. }
105.
106.
107.
108. /**
109. * 产生HmacSHA256摘要算法的密钥
110. */
111. public static byte[] initHmacSHA384Key() throws NoSuchAlgorithmException {
112. // 初始化HmacMD5摘要算法的密钥产生器
113. KeyGenerator generator = KeyGenerator.getInstance("HmacSHA384");
114. // 产生密钥
115. SecretKey secretKey = generator.generateKey();
116. // 获得密钥
117. byte[] key = secretKey.getEncoded();
118. return key;
119. }
120.
121. /**
122. * HmacSHA1摘要算法
123. * 对于给定生成的不同密钥,得到的摘要消息会不同,所以在实际应用中,要保存我们的密钥
124. */
125. public static String encodeHmacSHA384(byte[] data, byte[] key) throws Exception {
126. // 还原密钥
127. SecretKey secretKey = new SecretKeySpec(key, "HmacSHA384");
128. // 实例化Mac
129. Mac mac = Mac.getInstance(secretKey.getAlgorithm());
130. //初始化mac
131. mac.init(secretKey);
132. //执行消息摘要
133. byte[] digest = mac.doFinal(data);
134. return new HexBinaryAdapter().marshal(digest);//转为十六进制的字符串
135. }
136.
137.
138.
139. /**
140. * 产生HmacSHA256摘要算法的密钥
141. */
142. public static byte[] initHmacSHA512Key() throws NoSuchAlgorithmException {
143. // 初始化HmacMD5摘要算法的密钥产生器
144. KeyGenerator generator = KeyGenerator.getInstance("HmacSHA512");
145. // 产生密钥
146. SecretKey secretKey = generator.generateKey();
147. // 获得密钥
148. byte[] key = secretKey.getEncoded();
149. return key;
150. }
151.
152. /**
153. * HmacSHA1摘要算法
154. * 对于给定生成的不同密钥,得到的摘要消息会不同,所以在实际应用中,要保存我们的密钥
155. */
156. public static String encodeHmacSHA512(byte[] data, byte[] key) throws Exception {
157. // 还原密钥
158. SecretKey secretKey = new SecretKeySpec(key, "HmacSHA512");
159. // 实例化Mac
160. Mac mac = Mac.getInstance(secretKey.getAlgorithm());
161. //初始化mac
162. mac.init(secretKey);
163. //执行消息摘要
164. byte[] digest = mac.doFinal(data);
165. return new HexBinaryAdapter().marshal(digest);//转为十六进制的字符串
166. }
167. }
168.
169. public class MACTest {
170. public static void main(String[] args) throws Exception {
171. String testString = "asdasd";
172.
173. byte[] keyHmacMD5=MACCoder.initHmacMD5Key();
174. System.out.println(MACCoder.encodeHmacMD5(testString.getBytes(),keyHmacMD5));
175.
176. byte[] keyHmacSHA1=MACCoder.initHmacSHAKey();
177. System.out.println(MACCoder.encodeHmacSHA(testString.getBytes(),keyHmacSHA1));
178.
179. byte[] keyHmacSHA256=MACCoder.initHmacSHA256Key();
180. System.out.println(MACCoder.encodeHmacSHA256(testString.getBytes(),keyHmacSHA256));
181.
182. byte[] keyHmacSHA384=MACCoder.initHmacSHA384Key();
183. System.out.println(MACCoder.encodeHmacSHA384(testString.getBytes(),keyHmacSHA384));
184.
185. byte[] keyHmacSHA512=MACCoder.initHmacSHA512Key();
186. System.out.println(MACCoder.encodeHmacSHA512(testString.getBytes(),keyHmacSHA512));
187. }
188. }