Java MD5/SHA/MAC消息摘要算法
程序员文章站
2024-03-19 13:31:40
...
消息摘要算法
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");
}
}
运行结果:
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
消息摘要算法–应用
注册、登录密码处理
消息摘要算法–SHA
SHA(Secure Hash Algorithm) 安全散列算法的简称。
固定长度摘要信息
SHA-1, SHA-2(SHA-224, SHA-256, SHA-384, SHA-512)
算法 | 摘要长度 | 实现方法 |
---|---|---|
SHA-1 | 160 | JDK |
SHA-224 | 224 | Bouncy Castle/JDK1.8 |
SHA-256 | 256 | JDK |
SHA-384 | 384 | JDK |
SHA-512 | 512 | JDK |
代码实现
package md.test;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import org.apache.commons.codec.binary.Hex;
import org.apache.commons.codec.digest.DigestUtils;
import org.bouncycastle.crypto.Digest;
import org.bouncycastle.crypto.digests.SHA1Digest;
import org.bouncycastle.crypto.digests.SHA224Digest;
import org.bouncycastle.crypto.digests.SHA256Digest;
import org.bouncycastle.crypto.digests.SHA384Digest;
import org.bouncycastle.crypto.digests.SHA512Digest;
/**
* Secure Hash Algorithm
* @author Capricorncd
* https://github.com/capricorncd
*/
public class TestSHA {
private static final String SHA = "SHA";
private static final String SHA_224 = "SHA-224";
private static final String SHA_256 = "SHA-256";
private static final String SHA_384 = "SHA-384";
private static final String SHA_512 = "SHA-512";
public static void main(String[] args) {
String src = "Test Secure Hash Algorithm.";
// JDK
jdkSHA(src, SHA);
jdkSHA(src, SHA_224);
jdkSHA(src, SHA_256);
jdkSHA(src, SHA_384);
jdkSHA(src, SHA_512);
// Bouncy Castle
println("");
bcSHA(src, SHA, new SHA1Digest());
bcSHA(src, SHA_224, new SHA224Digest());
bcSHA(src, SHA_256, new SHA256Digest());
bcSHA(src, SHA_384, new SHA384Digest());
bcSHA(src, SHA_512, new SHA512Digest());
// org.apache.commons.codec.digest.DigestUtils
println("");
ccSHA(src, SHA);
ccSHA(src, SHA_224);
ccSHA(src, SHA_256);
ccSHA(src, SHA_384);
ccSHA(src, SHA_512);
}
/**
* JDK SHA
* @param src source
* @param algorithm algorithm type
*/
public static void jdkSHA(String src, String algorithm) {
String result = null;
try {
MessageDigest md = MessageDigest.getInstance(algorithm);
byte[] mdBytes = md.digest(src.getBytes());
result = Hex.encodeHexString(mdBytes);
} catch (NoSuchAlgorithmException e) {
// e.printStackTrace();
result = e.getMessage();
}
println(algorithm + ":", result, "by JDK");
}
/**
* Bouncy Castle SHA
* @param <T> Digest
* @param src source
* @param algorithm
* @param digest Digest
*/
public static<T extends Digest> void bcSHA(String src, String algorithm, T digest) {
// input bytes
byte[] srcBytes = src.getBytes();
digest.update(srcBytes, 0, srcBytes.length);
// result bytes
byte[] resBytes = new byte[digest.getDigestSize()];
digest.doFinal(resBytes, 0);
// to Hex
String result = org.bouncycastle.util.encoders.Hex.toHexString(resBytes);
println(algorithm + ":", result, "by Bouncy Castle");
}
/**
* org.apache.commons.codec.digest.DigestUtils
* @param src
* @param algorithm
*/
public static void ccSHA(String src, String algorithm) {
String result = null;
try {
switch(algorithm) {
case SHA:
result = DigestUtils.sha1Hex(src);
break;
case SHA_224:
result = DigestUtils.sha3_224Hex(src);
break;
case SHA_256:
result = DigestUtils.sha256Hex(src);
break;
case SHA_384:
result = DigestUtils.sha384Hex(src);
break;
case SHA_512:
result = DigestUtils.sha512Hex(src);
break;
}
} catch (Exception e) {
result = e.getMessage();
}
println(algorithm + ":", result, "by org.apache.commons.codec.digest.DigestUtils");
}
/**
* System.out.println
* @param args
*/
public static void println(Object ...args) {
for (Object o : args) {
System.out.print(o + " ");
}
System.out.print("\n");
}
}
运行结果:
SHA: 1ec4fe70c8223dbf362dd02481d2abe032aeaa23 by JDK
SHA-224: 7ce9d2ecd24444271fd823c8ded2931fa35ae70c747350004bce6291 by JDK
SHA-256: fc0de412e726341a95ae30b8ede3dfbb502fa50f9532439e45ca86cdfa725489 by JDK
SHA-384: 75cd6f06373ff58d7f50d02a68116108d1c56761e401f20dda6a3fa863b477bb2ce2030d8c760bf9da228d4623262273 by JDK
SHA-512: 9e9b3e31616ac90d2ec9981a2ba05c2045af58af9c279aa5d9fc45248982fe4eafaeccc12270310c2819b5b8b7541f5d9ba884bfac1b3c3fdfe8c42adb283643 by JDK
SHA: 1ec4fe70c8223dbf362dd02481d2abe032aeaa23 by Bouncy Castle
SHA-224: 7ce9d2ecd24444271fd823c8ded2931fa35ae70c747350004bce6291 by Bouncy Castle
SHA-256: fc0de412e726341a95ae30b8ede3dfbb502fa50f9532439e45ca86cdfa725489 by Bouncy Castle
SHA-384: 75cd6f06373ff58d7f50d02a68116108d1c56761e401f20dda6a3fa863b477bb2ce2030d8c760bf9da228d4623262273 by Bouncy Castle
SHA-512: 9e9b3e31616ac90d2ec9981a2ba05c2045af58af9c279aa5d9fc45248982fe4eafaeccc12270310c2819b5b8b7541f5d9ba884bfac1b3c3fdfe8c42adb283643 by Bouncy Castle
SHA: 1ec4fe70c8223dbf362dd02481d2abe032aeaa23 by org.apache.commons.codec.digest.DigestUtils
SHA-224: java.security.NoSuchAlgorithmException: SHA3-224 MessageDigest not available by org.apache.commons.codec.digest.DigestUtils
SHA-256: fc0de412e726341a95ae30b8ede3dfbb502fa50f9532439e45ca86cdfa725489 by org.apache.commons.codec.digest.DigestUtils
SHA-384: 75cd6f06373ff58d7f50d02a68116108d1c56761e401f20dda6a3fa863b477bb2ce2030d8c760bf9da228d4623262273 by org.apache.commons.codec.digest.DigestUtils
SHA-512: 9e9b3e31616ac90d2ec9981a2ba05c2045af58af9c279aa5d9fc45248982fe4eafaeccc12270310c2819b5b8b7541f5d9ba884bfac1b3c3fdfe8c42adb283643 by org.apache.commons.codec.digest.DigestUtils
SHA-应用
加入约定key,增加时间戳,排序
https://*?msg=f58d7f50d02a...16×tamp=1590324555411
msg: 原始消息+key+时间戳
消息摘要算法–MAC
MAC(Message Authentication Code)
HMAC(keyed-Hash Message Authentication Code),含有**的散列函数算法
融合MD、SHA
-
MD系列:HmacMD2、HmacMD4、HmacMD5
-
SHA系列:HmacSHA1、HmacSHA224、HmacSHA256、HmacSHA384、HmacSHA512
应用:SecureCRT
算法 | 摘要长度 | 实现方法 |
---|---|---|
HmacMD2 | 128 | Bouncy Castle |
HmacMD4 | 128 | Bouncy Castle |
HmacMD5 | 128 | JDK |
HmacSHA1 | 160 | JDK |
HmacSHA224 | 224 | Bouncy Castle/JDK1.8 |
HmacSHA256 | 256 | JDK |
HmacSHA384 | 384 | JDK |
HmacSHA512 | 512 | JDK |
代码实现
package md.test;
import javax.crypto.KeyGenerator;
import javax.crypto.Mac;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import org.apache.commons.codec.binary.Hex;
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.crypto.digests.SHA1Digest;
import org.bouncycastle.crypto.digests.SHA224Digest;
import org.bouncycastle.crypto.digests.SHA256Digest;
import org.bouncycastle.crypto.digests.SHA384Digest;
import org.bouncycastle.crypto.digests.SHA512Digest;
import org.bouncycastle.crypto.macs.HMac;
import org.bouncycastle.crypto.params.KeyParameter;
/**
* keyed-Hash Message Authentication Code
* @author Capricorncd
* https://github.com/capricorncd
*/
public class TestMAC {
private static final String HMAC_MD2 = "HmacMD2";
private static final String HMAC_MD4 = "HmacMD4";
private static final String HMAC_MD5 = "HmacMD5";
private static final String HMAC_SHA = "HmacSHA1";
private static final String HMAC_SHA_224 = "HmacSHA224";
private static final String HMAC_SHA_256 = "HmacSHA256";
private static final String HMAC_SHA_384 = "HmacSHA384";
private static final String HMAC_SHA_512 = "HmacSHA512";
public static void main(String[] args) {
String src = "keyed-Hash Message Authentication Code";
// secret key, length = 10.
String secretKey = "aaaaaaaaaa";
byte[] secretKeyBytes = org.bouncycastle.util.encoders.Hex.decode(secretKey);
jdkHmac(src, HMAC_MD2, secretKeyBytes);
jdkHmac(src, HMAC_MD4, secretKeyBytes);
jdkHmac(src, HMAC_MD5, secretKeyBytes);
println();
bcHmac(src, HMAC_MD2, new MD2Digest(), secretKeyBytes);
bcHmac(src, HMAC_MD4, new MD4Digest(), secretKeyBytes);
bcHmac(src, HMAC_MD5, new MD5Digest(), secretKeyBytes);
println();
jdkHmac(src, HMAC_SHA, secretKeyBytes);
jdkHmac(src, HMAC_SHA_224, secretKeyBytes);
jdkHmac(src, HMAC_SHA_256, secretKeyBytes);
jdkHmac(src, HMAC_SHA_384, secretKeyBytes);
jdkHmac(src, HMAC_SHA_512, secretKeyBytes);
println();
bcHmac(src, HMAC_SHA, new SHA1Digest(), secretKeyBytes);
bcHmac(src, HMAC_SHA_224, new SHA224Digest(), secretKeyBytes);
bcHmac(src, HMAC_SHA_256, new SHA256Digest(), secretKeyBytes);
bcHmac(src, HMAC_SHA_384, new SHA384Digest(), secretKeyBytes);
bcHmac(src, HMAC_SHA_512, new SHA512Digest(), secretKeyBytes);
}
/**
* JDK HMAC
* @param src source
* @param algorithm
* @param secretKeyBytes secret key bytes
*/
public static void jdkHmac(String src, String algorithm, byte[] secretKeyBytes) {
String result = null;
try {
// restore secret key
SecretKey restoreSecretKey = new SecretKeySpec(secretKeyBytes, algorithm);
// instance MAC
Mac mac = Mac.getInstance(restoreSecretKey.getAlgorithm());
// initial MAC
mac.init(restoreSecretKey);
// run
byte[] resultBytes = mac.doFinal(src.getBytes());
result = Hex.encodeHexString(resultBytes);
} catch (Exception e) {
// e.printStackTrace();
result = e.getMessage();
}
println(algorithm + ":", result, "by JDK");
}
/**
* JDK HMAC
* Automatically generate a secret key
* @param src
* @param algorithm
*/
public static void jdkHmac(String src, String algorithm) {
try {
// Automatically generate a secret key
// initial KeyGenerator
KeyGenerator keyGenerator = KeyGenerator.getInstance(algorithm);
// create secret key
SecretKey secretKey = keyGenerator.generateKey();
// get secret key
byte[] secretKeyBytes = secretKey.getEncoded();
jdkHmac(src, algorithm, secretKeyBytes);
} catch (Exception e) {
// e.printStackTrace();
println(algorithm + ":", e.getMessage(), "by JDK");
}
}
/**
* bouncy castle HMAC
* @param <T> Digest
* @param src source
* @param algorithm
* @param digest Digest
* @param secretKeyBytes secret key bytes
*/
public static <T extends Digest> void bcHmac(String src, String algorithm, T digest, byte[] secretKeyBytes) {
HMac hmac = new HMac(digest);
// byte[] secretKeyBytes = org.bouncycastle.util.encoders.Hex.decode("aaaaaaaaaa");
hmac.init(new KeyParameter(secretKeyBytes));
byte[] srcBytes = src.getBytes();
hmac.update(srcBytes, 0, srcBytes.length);
byte[] resultBytes = new byte[hmac.getMacSize()];
hmac.doFinal(resultBytes, 0);
String result = org.bouncycastle.util.encoders.Hex.toHexString(resultBytes);
println(algorithm + ":", result, "by Bouncy Castle.");
}
/**
* System.out.println
*
* @param args
*/
public static void println(Object... args) {
for (Object o : args) {
System.out.print(o + " ");
}
System.out.print("\n");
}
}
运行结果:
HmacMD2: Algorithm HmacMD2 not available by JDK
HmacMD4: Algorithm HmacMD4 not available by JDK
HmacMD5: 60abad09ecbc7f234c3066b76209d657 by JDK
HmacMD2: cc2e396c39d58f3d6415eebfbf928744 by Bouncy Castle.
HmacMD4: 199828516cc1f41baa9536e095e73483 by Bouncy Castle.
HmacMD5: 60abad09ecbc7f234c3066b76209d657 by Bouncy Castle.
HmacSHA1: ee77ed44862c69ff1b93d81a2cab40b714aeac39 by JDK
HmacSHA224: 261be450a5b2f6e9dad0df89e14710c4a412ef89d4c9b8db76173c19 by JDK
HmacSHA256: a6c974f0b1025844d8266e3ab8f0402c8467c5878dcd9982216c46b6fd90d067 by JDK
HmacSHA384: 43a6703c1fa097ec80a1aec85b6f38eef34059c3b90dddce27c7fde3d5e7d716050a86aa09275b52c9378eb819774a32 by JDK
HmacSHA512: da98cf562dfaa094624ee28464dd0c4e0ade2a07fc28bb5b5aadeb0cef59e43ec9a3eeef51cf33a6e30c1611e1dc912fac3f1108db15a72e390e47579e4dad23 by JDK
HmacSHA1: ee77ed44862c69ff1b93d81a2cab40b714aeac39 by Bouncy Castle.
HmacSHA224: 261be450a5b2f6e9dad0df89e14710c4a412ef89d4c9b8db76173c19 by Bouncy Castle.
HmacSHA256: a6c974f0b1025844d8266e3ab8f0402c8467c5878dcd9982216c46b6fd90d067 by Bouncy Castle.
HmacSHA384: 43a6703c1fa097ec80a1aec85b6f38eef34059c3b90dddce27c7fde3d5e7d716050a86aa09275b52c9378eb819774a32 by Bouncy Castle.
HmacSHA512: da98cf562dfaa094624ee28464dd0c4e0ade2a07fc28bb5b5aadeb0cef59e43ec9a3eeef51cf33a6e30c1611e1dc912fac3f1108db15a72e390e47579e4dad23 by Bouncy Castle.
from 慕课网
上一篇: web安全/渗透测试--60--web服务器解析漏洞
下一篇: log4j 博客分类: 开源框架