版权声明:本文为博主 [小明同学爱思考] 原创文章,转载请注明出处。 https://blog.csdn.net/sinat_22840937/article/details/79772598
JDK、第三方库commons-codec和bouncy-castle均对这些有实现。
MD系列算法实现
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;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.Security;
public class MD {
private static String srcMsg = "imooc security md";
public static void main(String[] args) throws NoSuchAlgorithmException {
jdkMD(srcMsg, "MD5");
jdkMD(srcMsg, "MD2");
bcMD(srcMsg, MD5Digest.class);
bcMD(srcMsg, MD4Digest.class);
bcMD(srcMsg, MD2Digest.class);
bcMD4(srcMsg);
ccMD(srcMsg, "MD5");
ccMD(srcMsg, "MD2");
ccMD(srcMsg, "MD4");
}
/**
* JDK MD算法相关实现
*
* @param srcMsg 加密消息
* @param md 支持算法:MD2、MD5
*/
public static void jdkMD(String srcMsg, String md) {
try {
MessageDigest messageDigest = MessageDigest.getInstance(md);
byte[] bytes = messageDigest.digest(srcMsg.getBytes());
String encodedMsg = Hex.encodeHexString(bytes);
System.out.println(encodedMsg);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
}
/**
* Bouncy Castle MD算法实现
*
* @param srcMsg 加密消息
* @param digestClass 加密算法对应的实现类,支持的有:
* org.bouncycastle.crypto.digests.MD2Digest
* org.bouncycastle.crypto.digests.MD4Digest
* org.bouncycastle.crypto.digests.MD5Digest
*/
public static void bcMD(String srcMsg, Class<? extends Digest> digestClass) {
try {
Digest digest = digestClass.newInstance();
digest.update(srcMsg.getBytes(), 0, srcMsg.getBytes().length);
byte[] bytes = new byte[digest.getDigestSize()];
digest.doFinal(bytes, 0);
String encodedMsg = org.bouncycastle.util.encoders.Hex.toHexString(bytes);
System.out.println(encodedMsg);
} catch (IllegalAccessException | InstantiationException e) {
e.printStackTrace();
}
}
/**
* 另一种bouncy castle实现MD4的方式(好像是只有MD4可以这样)
*
* @param srcMsg 加密消息
*/
public static void bcMD4(String srcMsg) {
try {
Security.addProvider(new BouncyCastleProvider());
MessageDigest messageDigest = MessageDigest.getInstance("MD4");
byte[] bytes = messageDigest.digest(srcMsg.getBytes());
String encodedMsg = Hex.encodeHexString(bytes);
System.out.println(encodedMsg);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
}
/**
* commons-codec MD算法实现
*
* @param srcMsg 加密消息
* @param md 支持的加密算法:MD2、MD5
* @throws NoSuchAlgorithmException
*/
public static void ccMD(String srcMsg, String md) throws NoSuchAlgorithmException {
if ("MD5".equals(md)) {
String encodedMsg = DigestUtils.md5Hex(srcMsg.getBytes());
System.out.println(encodedMsg);
return;
}
if ("MD2".equals(md)) {
String encodedMsg = DigestUtils.md2Hex(srcMsg.getBytes());
System.out.println(encodedMsg);
return;
}
throw new NoSuchAlgorithmException("only support for MD2 and MD5");
}
}
SHA系列算法的思想
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.SHA3Digest;
import org.bouncycastle.crypto.digests.SHA512Digest;
import org.bouncycastle.crypto.digests.SHAKEDigest;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.Security;
public class SHA {
private static String srcMsg = "imooc security sha";
public static void main(String[] args) throws NoSuchAlgorithmException {
jdkSHA1(srcMsg);
bcSHA(srcMsg, BouncyCastleSHAEnum.SHA1);
bcSHA224(srcMsg);
ccSHA(srcMsg, "SHA1");
ccSHA(srcMsg, "SH224");
}
/**
* jdk 实现SHA1算法
*
* @param srcMsg 加密消息
*/
public static void jdkSHA1(String srcMsg) {
try {
MessageDigest messageDigest = MessageDigest.getInstance("SHA");
messageDigest.update(srcMsg.getBytes());
String encodedMsg = Hex.encodeHexString(messageDigest.digest());
System.out.println(encodedMsg);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
}
/**
* 第三方库Bouncy Castle实现的SHA算法枚举类
*/
public enum BouncyCastleSHAEnum {
SHA1(new SHA1Digest()),
SHA3(new SHA3Digest()),
SHA224(new SHA224Digest()),
SHA256(new SHA256Digest()),
SHA384(new SHA384Digest()),
SHA512(new SHA512Digest()),
SHAKE(new SHAKEDigest()),;
private Digest digest;
BouncyCastleSHAEnum(Digest digest) {
this.digest = digest;
}
public Digest getDigest() {
return digest;
}
}
/**
* Bouncy Castle实现的SHA算法
*
* @param srcMsg 签名消息
* @param sha BouncyCastleSHAEnum
*/
public static void bcSHA(String srcMsg, BouncyCastleSHAEnum sha) {
Digest digest = sha.getDigest();
digest.update(srcMsg.getBytes(), 0, srcMsg.getBytes().length);
byte[] bytes = new byte[digest.getDigestSize()];
digest.doFinal(bytes, 0);
String encodedMsg = org.bouncycastle.util.encoders.Hex.toHexString(bytes);
System.out.println(encodedMsg);
}
/**
* 这种方法适用于SHA224、SHA256、SHA384、SHA512算法,其他可执行算法是指还是通过jdk支持实现的
*
* @param srcMsg
*/
public static void bcSHA224(String srcMsg) {
try {
Security.addProvider(new BouncyCastleProvider());
MessageDigest messageDigest = MessageDigest.getInstance("SHA224");
byte[] bytes = messageDigest.digest(srcMsg.getBytes());
String encodedMsg = Hex.encodeHexString(bytes);
System.out.println(encodedMsg);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
}
/**
* commons-coodec 实现的SHA相关算法(实际是对jdk sha实现的再次封装)
*
* @param srcMsg 加密消息
* @param sha 加密算法
* @throws NoSuchAlgorithmException
*/
public static void ccSHA(String srcMsg, String sha) throws NoSuchAlgorithmException {
if ("SHA1".equals(sha)) {
String encodedMsg = DigestUtils.sha1Hex(srcMsg);
System.out.println(encodedMsg);
return;
}
if ("SHA256".equals(sha)) {
String encodedMsg = DigestUtils.sha256Hex(srcMsg);
System.out.println(encodedMsg);
return;
}
if ("SHA384".equals(sha)) {
String encodedMsg = DigestUtils.sha384Hex(srcMsg);
System.out.println(encodedMsg);
return;
}
if ("SHA512".equals(sha)) {
String encodedMsg = DigestUtils.sha512Hex(srcMsg);
System.out.println(encodedMsg);
return;
}
throw new NoSuchAlgorithmException("Only support for [SHA1,SHA256,SHA384,SHA512]");
}
}
HMAC系列算法的思想
import org.apache.commons.codec.DecoderException;
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;
import javax.crypto.KeyGenerator;
import javax.crypto.Mac;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
/**
* MAC: Message Authentication Code
* HMAc:Keyed-Hash Message Authentication Code
* 常见的实现算法有:HmacMD2,HmacMD4,HmacMD5,HmacSHA1,HmacSHA224,HmacSHA256,HmacSHA384,HmacSHA512
*/
public class Hmac {
private static String srcMsg = "imooc security hmac";
public static void main(String[] args) {
jdkHmacMD5(srcMsg);
bcHmacMD5(srcMsg);
}
public static void jdkHmacMD5(String srcMsg) {
try {
//初始化KeyGenerator
KeyGenerator keyGenerator = KeyGenerator.getInstance("HmacMD5");
//产生密钥
SecretKey secretKey = keyGenerator.generateKey();
//获得密钥
// byte[] key = secretKey.getEncoded();
byte[] key = Hex.decodeHex(new char[]{'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a'});
//还原密钥
SecretKey restoreSecretKey = new SecretKeySpec(key, "HmacMd5");
//实例化Mac
Mac mac = Mac.getInstance(restoreSecretKey.getAlgorithm());
//初始化MAC
mac.init(restoreSecretKey);
byte[] bytes = mac.doFinal(srcMsg.getBytes());
String encodedMsg = Hex.encodeHexString(bytes);
System.out.println(encodedMsg);
} catch (NoSuchAlgorithmException | InvalidKeyException | DecoderException e) {
e.printStackTrace();
}
}
public static void bcHmacMD5(String srcMsg) {
HMac hMac = new HMac(new MD5Digest());
hMac.init(new KeyParameter(org.bouncycastle.util.encoders.Hex.decode("aaaaaaaaaa")));
hMac.update(srcMsg.getBytes(), 0, srcMsg.getBytes().length);
byte[] bytes = new byte[hMac.getMacSize()];
hMac.doFinal(bytes, 0);
String encodedMsg = Hex.encodeHexString(bytes);
System.out.println(encodedMsg);
}
}