Java加密解密之消息摘要算法MD5 SHA MAC
本文转自网络
消息摘要
消息摘要Message Digest又称为数字摘要(Digital Digest)。它是一个唯一对应一个消息或文本的固定长度的值它由一个单向Hash加密函数对消息进行作用而产生。如果消息在途中改变了则接收者通过对收到消息的新产生的摘要与原摘要比较就可知道消息是否被改变了。因此消息摘要保证了消息的完整性。消息摘要采用单向Hash函数将需加密的明文"摘要"成一串128bit的密文这一串密文亦称为数字指纹(FingerPrint)它有固定的长度且不同的明文摘要成密文其结果总是不同的而同样的明文其摘要必定一致。这样这串摘要便可成为验证明文是否是"真身"的"指纹"了。
HASH函数的抗冲突性使得如果一段明文稍有变化哪怕只更改该段落的一个字母通过哈希算法作用后都将产生不同的值。而HASH算法的单向性使得要找到到哈希值相同的两个不同的输入消息在计算上是不可能的。所以数据的哈希值即消息摘要可以检验数据的完整性。哈希函数的这种对不同的输入能够生成不同的值的特性使得无法找到两个具有相同哈希值的输入。因此如果两个文档经哈希转换后成为相同的值就可以肯定它们是同一文档。所以 当希望有效地比较两个数据块时就可以比较它们的哈希值。例如可以通过比较邮件发送前和发送后的哈希值来验证该邮件在传递时是否修改。
消息摘要算法
消息摘要算法的主要特征是加密过程不需要密钥并且经过加密的数据无法被解密只有输入相同的明文数据经过相同的消息摘要算法才能得到相同的密文。消息摘要算法不存在密钥的管理与分发问题适合于分布式网络相同上使用。 由于其加密计算的工作量相当可观所以以前的这种算法通常只用于数据量有限的情况下的加密例如计算机的口令就是用不可逆加密算法加密的。近年来随着计算机相同性能的飞速改善加密速度不再成为限制这种加密技术发展的桎梏因而消息摘要算法应用的领域不断增加。
消息摘要算法的特点
①无论输入的消息有多长计算出来的消息摘要的长度总是固定的。
②消息摘要看起来是“随机的”。这些比特看上去是胡乱的杂凑在一起的。
③一般地只要输入的消息不同对其进行摘要以后产生的摘要消息也必不相同但相同的输入必会产生相同的输出。
④消息摘要函数是无陷门的单向函数即只能进行正向的信息摘要而无法从摘要中恢复出任何的消息甚至根本就找不到任何与原信息相关的信息。⑤好的摘要算法无法找到两条消息是它们的摘要相同。
现有的消息摘要算法
消息摘要算法包含MD、 SHA和MAC三大系列常用于验证数据的完整性是数据签名算法的核心算法。
MAC与MD和SHA不同MAC是含有密钥的散列函数算法我们也常把MAC称为HMAC。
JDK对消息摘要算法的支持
JDK6支持
MD2/MD5/SHA/SHA256/SHA384/SHA512/HmacMD5/HmacSHA1/HmacSHA256/HmacSHA384/HmacSHA512
使用到十六进制工具类Hex.java 见 java byte数组与十六进制字符串互转MD和SHA系列的java实现
DigestUti ls.java
J a va代码
1. import java.security.MessageDigest;
2. import java.security.NoSuchAlgorithmException;
3.
4. /**
5. * reference apache commons <a
6. * href="http://commons.apache.org/codec/">http://commons.apache.org/codec/<
/a>
7. *
8. * support MD2/MD5/SHA/SHA256/SHA384/SHA512
9. * @author Aub
10. *
11. */
12. public class DigestUtils {
13.
14. /**
15. *根据给定摘要算法创建一个消息摘要实例
16. *
17. * @param algorithm
18. * 摘要算法名
19. * @return消息摘要实例
20. * @see MessageDigest#getInstance(String)
21. * @throws RuntimeException
22. * 当{@link java.security.NoSuchAlgorithmException}发生时
23. */
24. static MessageDigest getDigest(String algorithm) {
25. try {
26. return MessageDigest.getInstance(algorithm) ;
27. } catch (NoSuchAlgorithmException e) {
28. throw new RuntimeException(e.getMessage( )) ;
29. }
30. }
31.
32. /**
33. *获取MD5消息摘要实例
34. *
35. * @return MD5消息摘要实例
36. * @throws RuntimeException
37. * 当{@link java.security.NoSuchAlgorithmException}发生时
38. */
39. private static MessageDigest getMd5Digest() {
40. return getDigest( "MD5");
41. }
42.
43. /**
44. *获取SHA-1消息摘要实例
45. *
46. * @return SHA-1消息摘要实例
47. * @throws RuntimeException
48. * 当{@link java.security.NoSuchAlgorithmException}发生时
49. */
50. private static MessageDigest getShaDigest() {
51. return getDigest( "SHA");
52. }
53.
54. /**
55. *获取SHA-256消息摘要实例
56. *
57. * @return SHA-256消息摘要实例
58. * @throws RuntimeException
59. * 当{@link java.security.NoSuchAlgorithmException}发生时
60. */
61. private static MessageDigest getSha256Digest( ) {
62. return getDigest( "SHA-256") ;
63. }
64.
65. /**
66. *获取SHA-384消息摘要实例
67. *
68. * @return SHA-384消息摘要实例
69. * @throws RuntimeException
70. * 当{@link java.security.NoSuchAlgorithmException}发生时
71. */
72. private static MessageDigest getSha384Digest( ) {
73. return getDigest( "SHA-384") ;
74. }
75.
76. /**
77. *获取SHA-512消息摘要实例
78. *
79. * @return SHA-512消息摘要实例
80. * @throws RuntimeException
81. * 当{@link java.security.NoSuchAlgorithmException}发生时
82. */
83. private static MessageDigest getSha512Digest( ) {
84. return getDigest( "SHA-512") ;
85. }
86.
87. /**
88. *使用MD 5消息摘要算法计算消息摘要
89. *
90. * @param data
91. * 做消息摘要的数据
92. * @return消息摘要长度为16的字节数组
93. */
94. public static byte[] encodeMD5(byte[ ] data) {
95. return getMd5Digest() .digest(data) ;
96. }
97.
98. /**
99. *使用MD 5消息摘要算法计算消息摘要
100. *
101. * @param data
102. * 做消息摘要的数据
103. * @return消息摘要长度为32的十六进制字符串
104. */
105. public static String encodeMD5Hex(byte[] data) {
106. return Hex.encodeHexStr(encodeMD5(data) );
107. }
108.
109. /**
110. *使用SHA-1消息摘要算法计算消息摘要
111. *
112. * @param data
113. * 做消息摘要的数据
114. * @return SHA-1消息摘要长度为20的字节数组
115. */
116. public static byte[] encodeSHA(byte[ ] data) {
117. return getShaDigest() .digest(data) ;
118. }
119.
120. /**
121. *使用SHA-1消息摘要算法计算消息摘要
122. *
123. * @param data
124. * 做消息摘要的数据
125. * @return SHA-1消息摘要长度为40的十六进制字符串
126. */
127. public static String encodeSHAHex(byte[] data) {
128. return Hex.encodeHexStr(getShaDigest( ) .digest(data) ) ;
129. }
130.
131. /**
132. *使用SHA-256消息摘要算法计算消息摘要
133. *
134. * @param data
135. * 做消息摘要的数据
136. * @return SHA-256消息摘要长度为32的字节数组
137. */
138. public static byte[] encodeSHA256(byte[] data) {
139. return getSha256Digest() .digest(data) ;
140. }
141.
142. /**
143. *使用SHA-256消息摘要算法计算消息摘要
144. *
145. * @param data
146. * 做消息摘要的数据
147. * @return SHA-256消息摘要长度为64的十六进制字符串
148. */
149. public static String encodeSHA256Hex(byte[] data) {
150. return Hex.encodeHexStr(encodeSHA256(data) );
151. }
152.
153. /**
154. *使用SHA-384消息摘要算法计算消息摘要
155. *
156. * @param data
157. * 做消息摘要的数据
158. * @return SHA-384消息摘要长度为43的字节数组
159. */
160. public static byte[] encodeSHA384(byte[] data) {
161. return getSha384Digest() .digest(data) ;
162. }
163.
164. /**
165. *使用SHA-384消息摘要算法计算消息摘要
166. *
167. * @param data
168. * 做消息摘要的数据
169. * @return SHA-384消息摘要长度为86的十六进制字符串
170. */
171. public static String encodeSHA384Hex(byte[] data) {
172. return Hex.encodeHexStr(encodeSHA384(data) );
173. }
174.
175. /**
176. *使用SHA-512消息摘要算法计算消息摘要
177. *
178. * @param data
179. * 做消息摘要的数据
180. * @return SHA-512消息摘要长度为64的字节数组
181. */
182. public static byte[] encodeSHA512(byte[] data) {
183. return getSha512Digest() .digest(data) ;
184. }
185.
186. /**
187. *使用SHA-512消息摘要算法计算消息摘要
188. *
189. * @param data
190. * 做消息摘要的数据
191. * @return SHA-512消息摘要长度为128的十六进制字符串
192. */
193. public static String encodeSHA512Hex(byte[] data) {
194. return Hex.encodeHexStr(encodeSHA512(data) );
195. }
196.
197. }
参考org.apache.commons.codec.digest.DigestUti ls
下载地址 http://commons.apache.org/codec/download_codec.cgiMAC系列的java实现
Hmac.java
J a va代码
1. import java.security.InvalidKeyException;
2. import java.security.Key;
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.
10. /**
11. * Hmac<br/>
12. * algorithm HmacMD5/HmacSHA/HmacSHA256/HmacSHA384/HmacSHA512
13. * @author Aub
14. */
15. public class Hmac {
16.
17. /**
18. *根据给定密钥生成算法创建密钥
19. *
20. * @param algorithm
21. * 密钥算法
22. * @return密钥
23. * @throws RuntimeException
24. * 当{@link java.security.NoSuchAlgorithmException}发生时
25. */
26. private static byte[ ] getHmacKey(String algorithm){
27. //初始化KeyGenerator
28. KeyGenerator keyGenerator = null;
29. try {
30. keyGenerator = KeyGenerator.getInstance(algorithm) ;
31. } catch (NoSuchAlgorithmException e) {
32. throw new RuntimeException(e.getMessage( )) ;
33. }
34. //产生密钥
35. SecretKey secretKey = keyGenerator.generateKey( );
36. //获得密钥
37. return secretKey.getEncoded() ;
38. }
39.
40. /**
41. *获取HmaMD5的密钥
42. *
43. * @return HmaMD5的密钥
44. * @throws RuntimeException
45. * 当{@link java.security.NoSuchAlgorithmException}发生时
46. */
47. public static byte[] getHmaMD5key(){
48. return getHmacKey("HmacMD5" );
49. }
50.
51. /**
52. *获取HmaSHA的密钥
53. *
54. * @return HmaSHA的密钥
55. * @throws RuntimeException
56. * 当{@link java.security.NoSuchAlgorithmException}发生时
57. */
58. public static byte[] getHmaSHAkey(){
59. return getHmacKey("HmacSHA1") ;
60. }
61.
62. /**
63. *获取HmaSHA256的密钥
64. *
65. * @return HmaSHA256的密钥
66. * @throws RuntimeException
67. * 当{@link java.security.NoSuchAlgorithmException}发生时
68. */
69. public static byte[] getHmaSHA256key(){
70. return getHmacKey("HmacSHA256") ;
71. }
72.
73. /**
74. *获取HmaSHA384的密钥
75. *
76. * @return HmaSHA384的密钥
77. * @throws RuntimeException
78. * 当{@link java.security.NoSuchAlgorithmException}发生时
79. */
80. public static byte[] getHmaSHA384key(){
81. return getHmacKey("HmacSHA384") ;
82. }
83.
84. /**
85. *获取HmaSHA512的密钥
86. *
87. * @return HmaSHA384的密钥
88. * @throws RuntimeException
89. * 当{@link java.security.NoSuchAlgorithmException}发生时
90. */
91. public static byte[] getHmaSHA512key(){
92. return getHmacKey("HmacSHA512") ;
93. }
94.
95. /**
96. *转换密钥
97. *
98. * @param key 二进制密钥
99. * @param algorithm密钥算法
100. * @return密钥
101. */
102. private static Key toKey(byte[ ] key,String algorithm){
103. //生成密钥
104. return new SecretKeySpec(key, algorithm);
105. }
106.
107. /**
108. *使用HmacMD5消息摘要算法计算消息摘要
109. *
110. * @param data做消息摘要的数据
111. * @param key密钥
112. * @return消息摘要长度为16的字节数组
113. */
114. public static byte[] encodeHmacMD5(byte[ ] data, Key key){
AlphaVPS是一家保加利亚本土主机商(DA International Group Ltd),提供VPS主机及独立服务器租用等,数据中心包括美国(洛杉矶/纽约)、德国、英国和保加利亚等,公司办公地点跟他们提供的保加利亚数据中心在一栋楼内,自有硬件,提供IPv4+IPv6,支持PayPal或者信用卡等方式付款。商家提供的大硬盘VPS主机,提供128GB-2TB磁盘,最低年付15欧元起,也可以选择...
GreenCloudVPS最近在新加坡DC2节点上了新机器,Dual Xeon Silver 4216 CPU,DDR4内存,10Gbps网络端口,推出了几款大硬盘VPS套餐,基于KVM架构,500GB磁盘起年付30美元。除了大硬盘套餐外,还加推了几款采用NVMe硬盘的常规套餐,最低年付20美元。不过需要提醒的是,机房非直连中国,尤其是电信用户ping值感人,包括新加坡DC1也是如此。大硬盘VPS...
#年终感恩活动#华纳云海外物理机688元/月,续费同价,50M CN2 GIA/100M国际大带宽可选,超800G 防御,不限流华纳云成立于2015年,隶属于香港联合通讯国际有限公司。拥有香港政府颁发的商业登记证明,作为APNIC 和 ARIN 会员单位,现有香港、美国等多个地区数据中心资源,百G丰富带宽接入,坚持为海内外用户提供自研顶级硬件防火墙服务,支持T B级超大防护带宽,单IP防护最大可达...