在介绍消息摘要算法之前我们先看平时使用的maven下载页面的信息,如下所示:

Java实现消息摘要算法加密_SHA

上图中提示用户在自己构建maven的时候,为了防止下载文件被损坏,建议用户使用Apache提供的公共KEYS验证发布包的签名。

  • 消息摘要算法

    MD(Message Digest)

    SHA(Secure Hash Algorithm)

    MAC(Message Authentication Code)

    消息摘要算法主要是为了验证数据的完整性,是数字签名的核心算法。由此可见maven的摘要算法采用的是SHA512。

  • 消息摘要算法--MD

    MD家族算法是128位摘要信息,分为MD2、MD4、MD5,MD类算法是一个单向的过程。如下表格所示各类算法实现方:

算法

摘要长度

实现方

MD2

128

JDK

MD4

128

Bouncy Castle

MD5

128

JDK

MD类算法应用实现

    MD5实现:


package com.bity.md;

import org.apache.commons.codec.binary.Hex;
import org.bouncycastle.crypto.Digest;
import org.bouncycastle.crypto.digests.MD4Digest;

import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

import static java.lang.System.*;

/**
* <p>Title: MdSecurity</p >
* <p>Description: MD类算法实现 </p >
* <p>Company: http://www.agree.com</p >
* <p>Project: security</p >
*
* @author <a href="mailto:weiqi@agree.com.cn">WEIQI</a>
* @version 1.0
* @date 2022-04-24 21:11
*/
public class MdSecurity {

private static final String SRC = "I'm MD Family";

public static void main(String[] args) {
md5Jdk();
md2Jdk();
bcMd4();
}

/**
* JDK-MD5算法实现
*
* @author: <a href="mailto:weiqi@agree.com.cn">WEIQI</a>
* @date: 2022-04-25 21:50
*/
private static void md5Jdk() {
try {
MessageDigest messageDigest = MessageDigest.getInstance("MD5");

byte[] md5Bytes = messageDigest.digest(SRC.getBytes(StandardCharsets.UTF_8));

out.println("message digest is : " + Hex.encodeHexString(md5Bytes));
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
}
}

    MD2实现:

 /**
* JDK-MD2算法实现
*
* @author: <a href="mailto:weiqi@agree.com.cn">WEIQI</a>
* @date: 2022-04-25 21:50
*/
private static void md2Jdk() {
try {
MessageDigest messageDigest = MessageDigest.getInstance("MD2");

byte[] md2Bytes = messageDigest.digest(SRC.getBytes(StandardCharsets.UTF_8));

out.println("message digest is : " + Hex.encodeHexString(md2Bytes));
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
}

    MD4实现:


/**
* Bouncy-Castle-MD4算法实现
*
* @author: <a href="mailto:weiqi@agree.com.cn">WEIQI</a>
* @date: 2022-04-25 21:50
*/
private static void bcMd4() {
Digest digest = new MD4Digest();
digest.update(SRC.getBytes(StandardCharsets.UTF_8), 0, SRC.getBytes().length);

byte[] md4Bytes = new byte[digest.getDigestSize()];

digest.doFinal(md4Bytes, 0);

out.println("bc md4 digest is : " + org.bouncycastle.util.encoders.Hex.toHexString(md4Bytes));
}

通过上面例子可以看出,JDK对于摘要算法的实现是通过MessageDigest 来处理的,对于第三方包提供的MD4算法,我们可以使用JDK提供的方式来处理,如下:


/**
* 通过JDK提供的provider添加第三方加密算法
*
* @author: <a href="mailto:weiqi@agree.com.cn">WEIQI</a>
* @date: 2022-04-25 21:59
*/
private static void bcProviderMd4() {

try {
Security.addProvider(new BouncyCastleProvider());
MessageDigest messageDigest = MessageDigest.getInstance("MD4");

byte[] md4Bytes = messageDigest.digest(SRC.getBytes(StandardCharsets.UTF_8));

out.println("bc md4 digest is : " + org.bouncycastle.util.encoders.Hex.toHexString(md4Bytes));
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
}

这里注意使用到了Security.addProvider(new BouncyCastleProvider());,我们在平时开发中建议多使用这种编程思想,让我们的代码有更好的扩展性。

  • 消息摘要算法--SHA

SHA是安全散列算法,是固定长度的摘要信息,SHA的发展是在MD系列之后,在很多场景下被认为是MD算法的继承者,SHA有着比较好的美国官方背景,是美国的国家安全局设计,被美国的国家标准研究院发布的一系列散列码函数(SHA-1,SHA-2(SHA-224、SHA-256、SHA-384、SHA-512))。SHA这种散列码是在MD4的基础上演进而来的,所以它也有着固定长度的摘要信息。如下表格所示各类算法实现方:

算法

摘要长度

实现方

SHA-1

160

JDK

SHA-224

224

Bouncy Castle

SHA-256

256

JDK

SHA-384

384

JDK

SHA-512

512

JDK

SHA类算法应用实现

SHA-1实现:

package com.bity.sha;

import org.apache.commons.codec.binary.Hex;

import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

import static java.lang.System.*;

/**
* <p>Title: ShaSecurity</p >
* <p>Description: SHA类算法实现 </p >
* <p>Company: http://www.agree.com</p >
* <p>Project: security</p >
*
* @author <a href="mailto:weiqi@agree.com.cn">WEIQI</a>
* @version 1.0
* @date 2022-04-24 21:37
*/
public class ShaSecurity {

private static String src = "I'm WINQI";

public static void main(String[] args) {
jdkSha1();
}

/**
* JDK-SHA1算法实现
*
* @author: <a href="mailto:weiqi@agree.com.cn">WEIQI</a>
* @date: 2022-04-25 22:13
*/
private static void jdkSha1() {

try {
MessageDigest messageDigest = MessageDigest.getInstance("SHA");
messageDigest.update(src.getBytes(StandardCharsets.UTF_8));
out.println("jdk sha-1 is : " + Hex.encodeHexString(messageDigest.digest()));
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}

}
}

对于其他几类算法的实现,在创建消息摘要对象的时候通过MessageDigest.getInstance("SHA")指定对应的算法即可。

  • 消息摘要算法--MAC

通常我们把MAC称为HMAC(Keyed-Hash Message Authentication code)含有密钥散列函数算法。融合了MD、SHA。

HMAC-MD系列有:HmacMD2、HmacMD4、HmacMD5。

HMAC-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

HmacSHA256

256

JDK

HmacSHA384

384

JDK

HmacSHA512

512

JDK

HmacMD5实现:


package com.bity.hmac;

import org.apache.commons.codec.binary.Hex;

import javax.crypto.KeyGenerator;
import javax.crypto.Mac;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;

import static java.lang.System.*;

/**
* <p>Title: Hmac</p >
* <p>Description: Hmac实现 </p >
* <p>Company: http://www.agree.com</p >
* <p>Project: security</p >
*
* @author <a href="mailto:weiqi@agree.com.cn">WEIQI</a>
* @version 1.0
* @date 2022-04-25 22:23
*/
public class Hmac {

private static final String SRC = "I'm HMAC Family";

public static void main(String[] args) {
jdkHmacMd5();
}

/**
* JDK-HmacMD5实现
*
* @author: <a href="mailto:weiqi@agree.com.cn">WEIQI</a>
* @date: 2022-04-25 22:33
*/
private static void jdkHmacMd5() {

try {
// 初始化 KeyGenerator
KeyGenerator keyGenerator = KeyGenerator.getInstance("HmacMD5");
// 产生秘钥
SecretKey secretKey = keyGenerator.generateKey();
// 获得秘钥
byte[] keys = secretKey.getEncoded();

// 还原秘钥
SecretKey restoreKey = new SecretKeySpec(keys, "HmacMD5");
// 实例化MAC
Mac mac = Mac.getInstance(restoreKey.getAlgorithm());
// 初始化Mac
mac.init(restoreKey);

//执行摘要
byte[] hmacMd5Bytes = mac.doFinal(SRC.getBytes(StandardCharsets.UTF_8));

out.println("hmac md5 digest is : " + Hex.encodeHexString(hmacMDdBytes));
} catch (NoSuchAlgorithmException | InvalidKeyException e) {
e.printStackTrace();
}
}
}

对于其他几种算法的实现和上面雷同,这里不做更多的编码实现。MAC消息摘要算法的消息传递时序如下所示:

Java实现消息摘要算法加密_MD5_02

以上内容就是Java中对于消息摘要算法的原理介绍及代码实现。

附加

关于加解密相关系列文章会在微信公众号《编程之艺术》中每天连载分享,感兴趣的朋友可以关注下,可以及时获取最新文章连载信息。

                                                      Java实现消息摘要算法加密_MD5_03