# 消息摘要算法

MD(Message Digest)

SHA(Secure Hash Algorithm)

MAC(Message Authentication Code)

其他如:RipeMD, Tiger, Whirlpool, GOST3411等,均由Bouncy Castle实现。

# 消息摘要算法--MD(Message Digest)

作用:验证数据的完整性

是数字签名核心算法

MD5

MD家族(128位摘要信息)-MD2,MD4

算法 摘要长度 实现方法
MD2 128 JDK
MD4 128 Bouncy Castle
MD5 128 JDK

# 代码实现

package md.test;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.Security;

import org.apache.commons.codec.binary.Hex;
import org.apache.commons.codec.digest.DigestUtils;
import org.bouncycastle.crypto.Digest;
import org.bouncycastle.crypto.digests.MD2Digest;
import org.bouncycastle.crypto.digests.MD4Digest;
import org.bouncycastle.crypto.digests.MD5Digest;
import org.bouncycastle.jce.provider.BouncyCastleProvider;

/**
 * Message Digest
 * @author Capricorncd
 * https://github.com/capricorncd
 *
 */
public class TestMessageDigest {
	
	private static final String MD2 = "MD2";
	private static final String MD4 = "MD4";
	private static final String MD5 = "MD5";

	public static void main(String[] args) {
		String src = "I love the world.";
		
		jdkMD(src, MD2);
		jdkMD(src, MD4);
		jdkMD(src, MD5);
		
		bcMD(src, MD2, new MD2Digest());
		bcMD(src, MD4, new MD4Digest());
		bcMD(src, MD5, new MD5Digest());
		
		bouncyCastleMD(src, MD2);
		bouncyCastleMD(src, MD4);
		bouncyCastleMD(src, MD5);
		
		ccMD(src, MD2);
		ccMD(src, MD4);
		ccMD(src, MD5);
	}
	
	/**
	 * JDK MD
	 * @param src source
	 * @param mdType MD2,MD5
	 * @return String result
	 */
	public static String jdkMD(String src, String mdType) {
		String result = null;
		try {
			MessageDigest md = MessageDigest.getInstance(mdType);
			byte[] mdBytes = md.digest(src.getBytes());
			// toHex
			result = Hex.encodeHexString(mdBytes);
		} catch (NoSuchAlgorithmException e) {
			// e.printStackTrace();
			result = e.getMessage();
		}
		println(mdType + ":", result, "by JDK");
		return result;
	}
	
	/**
	 * bouncy castle MD
	 * @param src source
	 * @param mdType message digest type
	 * @param digest org.bouncycastle.crypto.Digest
	 * @return String result
	 */
	public static<T extends Digest> String bcMD(String src, String mdType, T digest) {
		byte[] srcBytes = src.getBytes();
		digest.update(srcBytes, 0, srcBytes.length);
		byte[] resBytes = new byte[digest.getDigestSize()];
		digest.doFinal(resBytes, 0);
		String result = org.bouncycastle.util.encoders.Hex.toHexString(resBytes);
		println(mdType + ":", result, "by Bouncycastle");
		return result;
	}
	
	/**
	 * bouncy castle provider MD
	 * @param src source
	 * @param mdType message digest type
	 * @return String result
	 */
	public static String bouncyCastleMD(String src, String mdType) {
		String result = null;
		Security.addProvider(new BouncyCastleProvider());
		try {
			MessageDigest md = MessageDigest.getInstance(mdType);
			byte[] mdBytes = md.digest(src.getBytes());
			result = Hex.encodeHexString(mdBytes);
		} catch (NoSuchAlgorithmException e) {
			// e.printStackTrace();
			result = e.getMessage();
		}
		println(mdType + ":", result, "by BouncyCastleProvider");
		return result;
	}
	
	/**
	 * org.apache.commons.codec.digest.DigestUtils
	 * @param src source
	 * @param mdType message digest type
	 * @return String result
	 */
	public static String ccMD(String src, String mdType) {
		String result = null;
		switch(mdType) {
		case MD2:
			result = DigestUtils.md2Hex(src.getBytes());
			break;
		case MD4:
			result = "The MD4 method is not implemented.";
			break;
		case MD5:
			result = DigestUtils.md5Hex(src.getBytes());
			break;
		}
		println(mdType + ":", result, "by org.apache.commons.codec.digest.DigestUtils");
		return result;
	}
	
	/**
	 * System.out.println
	 * @param args
	 */
	public static void println(Object ...args) {
		for (Object o : args) {
			System.out.print(o + " ");
		}		
		System.out.print("\n");
	}
}
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
132
133
134
135
136
137
138
139

运行结果:

MD2: b749ef6943db8fa96fa688a1077224a3 by JDK
MD4: MD4 MessageDigest not available by JDK
MD5: 2947f614c460347649185e62ee914eac by JDK
MD2: b749ef6943db8fa96fa688a1077224a3 by Bouncycastle
MD4: 9df4c1b595403939d490ad7c66cf7710 by Bouncycastle
MD5: 2947f614c460347649185e62ee914eac by Bouncycastle
MD2: b749ef6943db8fa96fa688a1077224a3 by BouncyCastleProvider
MD4: 9df4c1b595403939d490ad7c66cf7710 by BouncyCastleProvider
MD5: 2947f614c460347649185e62ee914eac by BouncyCastleProvider
MD2: b749ef6943db8fa96fa688a1077224a3 by org.apache.commons.codec.digest.DigestUtils
MD4: The MD4 method is not implemented. by org.apache.commons.codec.digest.DigestUtils
MD5: 2947f614c460347649185e62ee914eac by org.apache.commons.codec.digest.DigestUtils
1
2
3
4
5
6
7
8
9
10
11
12

# 消息摘要算法--应用

注册、登录密码处理

message-digest-application