SHA1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
|
package com.stone.security; import java.io.ByteArrayInputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.security.DigestInputStream; import java.security.DigestOutputStream; import java.security.MessageDigest; import java.util.Arrays; import javax.crypto.Mac; import javax.crypto.SecretKey; import javax.crypto.SecretKeyFactory; import javax.crypto.spec.PBEKeySpec; public class SHA { public static void main(String[] args) throws Exception { encodeByMAC( "中國oP……&*()…&802134…" ); encodeBySHA( "中國oP……&*()…&802134…" ); shaFile(); } /** * 使用MAC 算法的 消息摘要 * @param data * @throws Exception */ public static void encodeByMAC(String data) throws Exception{ // KeyGenerator keyGen = KeyGenerator.getInstance("HmacSHA1"); // SecretKey key = keyGen.generateKey(); //這個每次生成的key不一樣, 此處不能使用 PBEKeySpec keySpec = new PBEKeySpec( "randomkey^(^&*^%$" .toCharArray()); SecretKeyFactory keyFactory = SecretKeyFactory.getInstance( "PBEWithMD5AndDES" ); SecretKey key = keyFactory.generateSecret(keySpec); /* * 此類提供“消息驗(yàn)證碼”(Message Authentication Code,MAC)算法的功能。 * MAC 基于秘密密鑰提供一種方式來檢查在不可靠介質(zhì)上進(jìn)行傳輸或存儲的信息的完整性。 * 通常,消息驗(yàn)證碼在共享秘密密鑰的兩個參與者之間使用,以驗(yàn)證這兩者之間傳輸?shù)男畔ⅰ? * 基于加密哈希函數(shù)的 MAC 機(jī)制也叫作 HMAC。結(jié)合秘密共享密鑰, * HMAC 可以用于任何加密哈希函數(shù)(如 MD5 或 SHA-1) */ Mac mac = Mac.getInstance("HmacSHA1"); //以下三種都可用 // Mac mac = Mac.getInstance("HmacSHA256"); // Mac mac = Mac.getInstance("HmacSHA384"); // Mac mac = Mac.getInstance("HmacSHA512"); mac.init(key); byte[] dest = mac.doFinal(data.getBytes()); System.out.println(dest.length); System.out.println("MAC摘要:" + Arrays.toString(dest)); } /** * SHA1加密 使用消息摘要MessageDigest 處理 * @throws Exception */ public static String encodeBySHA(String str) throws Exception{ MessageDigest sha1; sha1 = MessageDigest.getInstance("SHA1"); //以下三種不可用 // sha1 = MessageDigest.getInstance("SHA256"); // sha1 = MessageDigest.getInstance("SHA384"); // sha1 = MessageDigest.getInstance("SHA512"); sha1.update(str.getBytes()); //先更新摘要 byte[] digest = sha1.digest(); //再通過執(zhí)行諸如填充之類的最終操作完成哈希計(jì)算。在調(diào)用此方法之后,摘要被重置。 /* * 使用指定的 byte 數(shù)組對摘要進(jìn)行最后更新,然后完成摘要計(jì)算。 * 也就是說,此方法首先調(diào)用 update(input), * 向 update 方法傳遞 input 數(shù)組,然后調(diào)用 digest()。 */ // byte[] digest = sha1.digest(str.getBytes()); String hex = toHex(digest); System.out.println("SHA1摘要:" + hex); return hex; } /** * 文件數(shù)據(jù)摘要 * @throws Exception */ public static void shaFile() throws Exception { MessageDigest messageDigest = MessageDigest.getInstance("SHA1"); DigestOutputStream dos = new DigestOutputStream(new FileOutputStream(new File("abc.txt")), messageDigest); dos.write("中華人民……&())f*(214)admin*".getBytes()); dos.close(); byte[] digest = messageDigest.digest(); System.out.println("使用流寫文件,該文件的摘要為:" + toHex(digest)); DigestInputStream dis = new DigestInputStream(new FileInputStream(new File("abc.txt")), messageDigest); byte[] buf = new byte[100]; int len; while ((len = dis.read(buf)) != -1) { System.out.println("讀取到的數(shù)據(jù)為:" + new String(buf, 0, len)); } dis.close(); byte[] digest2 = messageDigest.digest(); //當(dāng)流讀取完畢,即將文件讀完了, 這時的摘要 才與 寫入時的 一樣 System.out.println("使用流讀文件,該文件的摘要為:" + toHex(digest2)); } /** * sha1 摘要轉(zhuǎn)16進(jìn)制 * @param digest * @return */ private static String toHex( byte [] digest) { StringBuilder sb = new StringBuilder(); int len = digest.length; String out = null ; for ( int i = 0 ; i < len; i++) { // out = Integer.toHexString(0xFF & digest[i] + 0xABCDEF); //加任意 salt out = Integer.toHexString( 0xFF & digest[i]); //原始方法 if (out.length() == 1 ) { sb.append( "0" ); //如果為1位 前面補(bǔ)個0 } sb.append(out); } return sb.toString(); } } |
MD5
MD5(Message Digest Algorithm 5),即消息摘要算法第五版。消息摘要是一種算法:無論原始數(shù)據(jù)多長,消息摘要的結(jié)果都是固定長度的;是一種不可逆的算法
原始數(shù)據(jù)任意bit位的變化,都會導(dǎo)致消息摘要的結(jié)果有很大的不同,且根據(jù)結(jié)果推算出原始數(shù)據(jù)的概率極低。
消息摘要可以看作原始數(shù)據(jù)的指紋,指紋不同則原始數(shù)據(jù)不同。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
|
package com.stone.security; import java.io.ByteArrayInputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.security.DigestInputStream; import java.security.DigestOutputStream; import java.security.MessageDigest; import java.util.Arrays; import javax.crypto.Mac; import javax.crypto.SecretKey; import javax.crypto.SecretKeyFactory; import javax.crypto.spec.PBEKeySpec; public class MD5 { public static void main(String[] args) throws Exception { encodeByMAC( "中國oP……&*()…&802134…" ); encodeByMd5( "中國oP……&*()…&802134…" ); md5File(); } /** * 使用MAC 算法的 消息摘要 * @param data * @throws Exception */ public static void encodeByMAC(String data) throws Exception{ // KeyGenerator keyGen = KeyGenerator.getInstance("HmacMD5"); // SecretKey key = keyGen.generateKey(); //這個每次生成的key不一樣, 此處不能使用 PBEKeySpec keySpec = new PBEKeySpec( "randomkey^(^&*^%$" .toCharArray()); SecretKeyFactory keyFactory = SecretKeyFactory.getInstance( "PBEWithMD5AndDES" ); SecretKey key = keyFactory.generateSecret(keySpec); /* * 此類提供“消息驗(yàn)證碼”(Message Authentication Code,MAC)算法的功能。 * MAC 基于秘密密鑰提供一種方式來檢查在不可靠介質(zhì)上進(jìn)行傳輸或存儲的信息的完整性。 * 通常,消息驗(yàn)證碼在共享秘密密鑰的兩個參與者之間使用,以驗(yàn)證這兩者之間傳輸?shù)男畔ⅰ? * 基于加密哈希函數(shù)的 MAC 機(jī)制也叫作 HMAC。結(jié)合秘密共享密鑰, * HMAC 可以用于任何加密哈希函數(shù)(如 MD5 或 SHA-1) */ Mac mac = Mac.getInstance("HmacMD5"); mac.init(key); byte[] dest = mac.doFinal(data.getBytes()); System.out.println(dest.length); System.out.println("MAC摘要:" + Arrays.toString(dest)); } /** * md5加密 使用消息摘要MessageDigest 處理 * @throws Exception */ public static String encodeByMd5(String str) throws Exception{ MessageDigest md5; md5 = MessageDigest.getInstance("MD5"); md5.update(str.getBytes()); //先更新摘要 byte[] digest = md5.digest(); //再通過執(zhí)行諸如填充之類的最終操作完成哈希計(jì)算。在調(diào)用此方法之后,摘要被重置。 /* * 使用指定的 byte 數(shù)組對摘要進(jìn)行最后更新,然后完成摘要計(jì)算。 * 也就是說,此方法首先調(diào)用 update(input), * 向 update 方法傳遞 input 數(shù)組,然后調(diào)用 digest()。 */ // byte[] digest = md5.digest(str.getBytes()); String hex = toHex(digest); System.out.println("MD5摘要:" + hex); return hex; } /** * 文件數(shù)據(jù)摘要 * @throws Exception */ public static void md5File() throws Exception { MessageDigest messageDigest = MessageDigest.getInstance("MD5"); DigestOutputStream dos = new DigestOutputStream(new FileOutputStream(new File("abc.txt")), messageDigest); dos.write("中華人民……&())f*(214)admin*".getBytes()); dos.close(); byte[] digest = messageDigest.digest(); System.out.println("使用流寫文件,該文件的摘要為:" + toHex(digest)); DigestInputStream dis = new DigestInputStream(new FileInputStream(new File("abc.txt")), messageDigest); byte[] buf = new byte[100]; int len; while ((len = dis.read(buf)) != -1) { System.out.println("讀取到的數(shù)據(jù)為:" + new String(buf, 0, len)); } dis.close(); byte[] digest2 = messageDigest.digest(); //當(dāng)流讀取完畢,即將文件讀完了, 這時的摘要 才與 寫入時的 一樣 System.out.println("使用流讀文件,該文件的摘要為:" + toHex(digest2)); } /** * md5 摘要轉(zhuǎn)16進(jìn)制 * @param digest * @return */ private static String toHex( byte [] digest) { StringBuilder sb = new StringBuilder(); int len = digest.length; String out = null ; for ( int i = 0 ; i < len; i++) { // out = Integer.toHexString(0xFF & digest[i] + 0xABCDEF); //加任意 salt out = Integer.toHexString( 0xFF & digest[i]); //原始方法 if (out.length() == 1 ) { sb.append( "0" ); //如果為1位 前面補(bǔ)個0 } sb.append(out); } return sb.toString(); } } |