MD、SHA、MAC消息摘要算法实现与应用
- 2019 年 10 月 3 日
- 筆記
1.??????
?????Message Digest?????????Digital Digest???????????????????????????????Hash????????????????????????????????????????????????????????????????????????????????
????????Hash?????????"??"?????????128bit??????????????????Finger Print??????????????????????????????????????????????????????????????“??”?“??”??
??????????????????????????????????????????????????????Hash??????????????????????????
2.??????-MD2?MD4?MD5
MD?????????????????? MD5?Message-Digest Algorithm 5?????????5????MD2?MD3?MD4??????Ron Rivest?RSA????1992???????????????????????????????????MD2?MD4?MD5 ???16???128??????????32?????????MD2???????????MD4????????????MD5?MD4?????????
????????????????????MD5???????????????MD5??????????? .md5?.md5sum????????????????????? SFV ??????????????????????????????????????????????????????????????????????????????????????????????????MD5 ?????????? WinMD5??
MD?????
?? | ???? | ??? |
---|---|---|
MD2 | 128 | JDK |
MD4 | 128 | Bouncy Castle |
MD5 | 128 | JDK |
????????Java??????????Bouncy Castle?Commons Codec????
<dependency> <groupId>org.bouncycastle</groupId> <artifactId>bcprov-jdk15</artifactId> <version>1.46</version> </dependency> <dependency> <groupId>commons-codec</groupId> <artifactId>commons-codec</artifactId> <version>1.10</version> </dependency>
Java?????
import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.security.Security; import org.apache.commons.codec.digest.DigestUtils; import org.bouncycastle.crypto.digests.MD4Digest; import org.bouncycastle.crypto.digests.MD5Digest; import org.bouncycastle.jce.provider.BouncyCastleProvider; public class MD5 { public static final String src = "md5 test"; public static void main(String[] args) throws NoSuchAlgorithmException { jdkMD5(); jdkMD2(); ccMD5(); ccMD2(); bcMD5(); bcMD4(); bc2jdkMD4(); } // ?jdk??:MD5 public static void jdkMD5() throws NoSuchAlgorithmException { MessageDigest md = MessageDigest.getInstance("MD5"); byte[] md5Bytes = md.digest(src.getBytes()); System.out.println("JDK MD5:" + bytesToHexString(md5Bytes)); } // ?jdk??:MD2 public static void jdkMD2() throws NoSuchAlgorithmException { MessageDigest md = MessageDigest.getInstance("MD2"); byte[] md2Bytes = md.digest(src.getBytes()); System.out.println("JDK MD2:" + bytesToHexString(md2Bytes)); } // ?bouncy castle??:MD5 public static void bcMD5() { MD5Digest digest = new MD5Digest(); digest.update(src.getBytes(), 0, src.getBytes().length); byte[] md5Bytes = new byte[digest.getDigestSize()]; digest.doFinal(md5Bytes, 0); System.out.println("bouncy castle MD5:" + bytesToHexString(md5Bytes)); } // ?bouncy castle??:MD4 public static void bcMD4() { MD4Digest digest = new MD4Digest(); digest.update(src.getBytes(), 0, src.getBytes().length); byte[] md4Bytes = new byte[digest.getDigestSize()]; digest.doFinal(md4Bytes, 0); System.out.println("bouncy castle MD4:" + bytesToHexString(md4Bytes)); } // ?bouncy castle?jdk????:MD4 public static void bc2jdkMD4() throws NoSuchAlgorithmException { Security.addProvider(new BouncyCastleProvider()); MessageDigest md = MessageDigest.getInstance("MD4"); byte[] md4Bytes = md.digest(src.getBytes()); System.out.println("bc and JDK MD4:" + bytesToHexString(md4Bytes)); } // ?common codes????:MD5 public static void ccMD5() { System.out.println("common codes MD5:" + DigestUtils.md5Hex(src.getBytes())); } // ?common codes????:MD2 public static void ccMD2() { System.out.println("common codes MD2:" + DigestUtils.md2Hex(src.getBytes())); } /** * byte[] ? 16?? */ private static String bytesToHexString(byte[] src) { StringBuilder stringBuilder = new StringBuilder(); if (src == null || src.length <= 0) { return null; } for (int i = 0; i < src.length; i++) { int v = src[i] & 0xFF; String hv = Integer.toHexString(v); if (hv.length() < 2) { stringBuilder.append(0); } stringBuilder.append(hv); } return stringBuilder.toString(); } }
MD???????????????????MD???????????????????????????????????????????????????????????????
3.??????-SHA
SHA?Secure Hash Algorithm??????????????????——????????????NIST?????SHA?????????????SHA-1?20???160???SHA-224?32???224???SHA-256?32???256???SHA-384?48???384???SHA-512?64???512???????????????????????????????????????????????????????SHA??????????????????????MD5?????????
??SHA1?????????????CA???????????????????BT????????SHA1?????????
SHA?????
?? | ???? | ??? |
---|---|---|
SHA-1 | 160 | JDK |
SHA-224 | 224 | Bouncy Castle |
SHA-256 | 256 | JDK |
SHA-384 | 384 | JDK |
SHA-512 | 512 | JDK |
Java?????
import java.io.UnsupportedEncodingException; import java.math.BigInteger; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.security.Security; 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.jce.provider.BouncyCastleProvider; public class SHA { public static final String src = "sha test"; public static void main(String[] args) throws UnsupportedEncodingException, NoSuchAlgorithmException { jdkSHA1(); bcSHA1(); bcSHA224(); bcSHA224b(); generateSha256(); ccSHA1(); } // ?jdk??:SHA1 public static void jdkSHA1() throws NoSuchAlgorithmException { MessageDigest md = MessageDigest.getInstance("SHA"); md.update(src.getBytes()); byte[] bytes = md.digest(); //byte[]?16?? BigInteger bigInt = new BigInteger(1, bytes); System.out.println("jdk sha-1:" + bigInt.toString(16)); } // ?jdk??:SHA256 public static void generateSha256() throws UnsupportedEncodingException, NoSuchAlgorithmException { MessageDigest md = MessageDigest.getInstance("SHA-256"); md.update(src.getBytes("UTF-8")); // Change this to "UTF-16" if needed byte[] digest = md.digest(); BigInteger bigInt = new BigInteger(1, digest); System.out.println("Sha256 hash: " + bigInt.toString(16)); } // ?bouncy castle??:SHA1 public static void bcSHA1() { Digest digest = new SHA1Digest(); digest.update(src.getBytes(), 0, src.getBytes().length); byte[] sha1Bytes = new byte[digest.getDigestSize()]; digest.doFinal(sha1Bytes, 0); BigInteger bigInt = new BigInteger(1, sha1Bytes); System.out.println("bc sha-1:" + bigInt.toString(16)); } // ?bouncy castle??:SHA224 public static void bcSHA224() { Digest digest = new SHA224Digest(); digest.update(src.getBytes(), 0, src.getBytes().length); byte[] sha224Bytes = new byte[digest.getDigestSize()]; digest.doFinal(sha224Bytes, 0); BigInteger bigInt = new BigInteger(1, sha224Bytes); System.out.println("bc sha-224:" + bigInt.toString(16)); } // ?bouncy castle?jdk????:SHA224 public static void bcSHA224b() throws NoSuchAlgorithmException { Security.addProvider(new BouncyCastleProvider()); MessageDigest md = MessageDigest.getInstance("SHA224"); md.update(src.getBytes()); BigInteger bigInt = new BigInteger(1, md.digest()); System.out.println("bc and JDK sha-224:" + bigInt.toString(16)); } // ?common codes????:SHA1 public static void ccSHA1() { System.out.println("common codes SHA1 - 1 :" + DigestUtils.sha1Hex(src.getBytes())); System.out.println("common codes SHA1 - 2 :" + DigestUtils.sha1Hex(src)); } }
?????
4.??????-MAC
MAC?? (Message Authentication Codes???????) ???????????????MD?SHA????????????????????MAC????????HMAC???????????????????????????Hash???MAC?
??MAC????????????????????????????????????????????? HmacSHA???????????SHA1????????????160?????????????????40??
?????
???????????????????
1.??????????????????????????
2.????????????????????????????????????????????????????????????????????????????????????????????
3.???????????????????????????????????
4.?????????????????????+?????? ???????????????????????????????????????????????????
MAC??????
?? | ???? | ?? |
---|---|---|
HmacMD5 | 128 | JAVA6?? |
HmacSHA1 | 160 | JAVA6?? |
HmacSHA256 | 256 | JAVA6?? |
HmacSHA384 | 384 | JAVA6?? |
HmacSHA512 | 512 | JAVA6?? |
HmacMD2 | 128 | BouncyCastle?? |
HmacMD4 | 128 | BouncyCastle?? |
HmacSHA224 | 224 | BouncyCastle?? |
Java?????
import java.math.BigInteger; 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.digests.MD5Digest; import org.bouncycastle.crypto.macs.HMac; import org.bouncycastle.crypto.params.KeyParameter; public class HMAC { public static final String src = "hmac test"; public static void main(String[] args) { jdkHmacMD5(); bcHmacMD5(); } // ?jdk??: public static void jdkHmacMD5() { try { // ???KeyGenerator KeyGenerator keyGenerator = KeyGenerator.getInstance("HmacMD5"); // ???? SecretKey secretKey = keyGenerator.generateKey(); // ???? // byte[] key = secretKey.getEncoded(); byte[] key = Hex.decodeHex(new char[]{'1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e'}); // ???? SecretKey restoreSecretKey = new SecretKeySpec(key, "HmacMD5"); // ???MAC Mac mac = Mac.getInstance(restoreSecretKey.getAlgorithm()); // ???MAC mac.init(restoreSecretKey); // ???? byte[] hmacMD5Bytes = mac.doFinal(src.getBytes()); System.out.println("jdk hmacMD5:" + Hex.encodeHexString(hmacMD5Bytes)); } catch (Exception e) { e.printStackTrace(); } } // ?bouncy castle??: public static void bcHmacMD5() { HMac hmac = new HMac(new MD5Digest()); // ???16???????????2??? hmac.init(new KeyParameter(org.bouncycastle.util.encoders.Hex.decode("123456789abcde"))); hmac.update(src.getBytes(), 0, src.getBytes().length); // ???? byte[] hmacMD5Bytes = new byte[hmac.getMacSize()]; hmac.doFinal(hmacMD5Bytes, 0); BigInteger bigInteger = new BigInteger(1,hmacMD5Bytes); System.out.println("bc hmacMD5:" + bigInteger.toString(16)); } }