PKI - 消息摘要算法 - MD、SHA、MAC - 校验数据完整性

2024-04-25 18:38

本文主要是介绍PKI - 消息摘要算法 - MD、SHA、MAC - 校验数据完整性,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

PKI - 消息摘要算法 - MD、SHA、MAC - 校验数据完整性

  • 1. MD5
    • 1.1 JDK实现
    • 1.2 Bouncy Castle实现
    • 1.3 Commons Codec
  • 2. SHA
    • 2.1 JDK实现
    • 2.2 Bouncy Castle实现
    • 2.3 Commons Codec
  • 3. MAC
    • 3.1 JDK
    • 3.2 Bouncy Castle
  • 4. 其他消息摘要算法
  • 5. 循环冗余校验算法 -- CRC算法
  • 6. 扩展
    • 6.1 “挑战/响应”身份认证
  • 参考

消息摘要算法又称散列算法,其核心在于散列函数的单向性。即通过散列函数可获得对应的散列值,但不可通过该散列值反推其原始信息。这是消息摘要算法的安全性的根本所在。

消息摘要算法主要分为三大类:MD(Message Digest,消息摘要算法)、SHA(Secure Hash Algorithm,安全散列算法)和MAC(Message Authentication Code,消息认证码算法)。

MD系列算法包括MD2、MD4和MD5共3种算法;
SHA算法主要包括其代表算法SHA1和SHA1算法的变种SHA2系列算法(SHA224、SHA256、SHA384、SHA512)以及SHA3(SHA3-224、SHA3-256、SHA3-384、SHA3-512等);SHA-2的算法和SHA1是一样的,区别在于其生成的摘要的长度;SHA-3是与SHA-2算法不同的,可替换的加密散列算法。
MAC算法综合了上述两种算法,主要包括HmacMD5HmacSHA1HmacSHA256、HmacSHA384和HmacSHA512算法。

尽管上述内容列举了各种消息摘要算法,但仍不能满足应用需要。基于这些消息摘要算法,又衍生出了RipeMD系列(包含RipeMD128、RipeMD160、RipeMD256、RipeMD320)、Tiger、GOST3411和Whirlpool算法。

1. MD5

1.1 JDK实现

java.security 包提供 java.security.MessageDigest 类进行消息摘要处理,输出字节数组。
消息摘要的一个特点是每次输出的摘要值都相同,下面的Test-Case对此进行了验证。

public byte[] md5Jdk8(String data) throws Exception {return MessageDigest.getInstance("MD5").digest(data.getBytes("UTF-8"));
}@Test
public void md5Jdk8Test() throws Exception {final byte[] md5_1 = md5Jdk8("我是阿汤哥");final byte[] md5_2 = md5Jdk8("我是阿汤哥");assertEquals(md5_1, md5_2);
}

1.2 Bouncy Castle实现

要使用BC实现需要添加provider,Security.addProvider(new BouncyCastleProvider()),同时可以将字节数组转换为16进制编码的字符串进行输出。

public String md5Bc(String data) throws Exception {// 加入Bouncy Castle Provider支持Security.addProvider(new BouncyCastleProvider());final byte[] md5s = MessageDigest.getInstance("MD5").digest(data.getBytes("UTF-8"));return new String(Hex.encode(md5s), "UTF-8");
}@Test
public void md5BcTest() throws Exception {final String md5_1 = md5Bc("我是阿汤哥");final String md5_2 = md5Bc("我是阿汤哥");System.out.println("MD5 first  : " + md5_1);System.out.println("MD5 second : " + md5_2);assertEquals(md5_1, md5_2);
}

1.3 Commons Codec

org.apache.commons.codec.digest.DigestUtils,虽然DigestUtils只是对MessageDigist的简单封装,但为实际开发提供了不少便利。

public String md5Codec(String data) throws Exception {return DigestUtils.md5Hex(data);
}@Test
public void md5CodecTest() throws Exception {final String md5_1 = md5Codec("我是阿汤哥");final String md5_2 = md5Codec("我是阿汤哥");System.out.println("MD5 first  : " + md5_1);System.out.println("MD5 second : " + md5_2);assertEquals(md5_1, md5_2);
}

输出结果

MD5 first  : 15e13fd90ab9822cf0ea4e1d29301535
MD5 second : 15e13fd90ab9822cf0ea4e1d29301535

2. SHA

SHA(Secure Hash Algorithm,安全散列算法)是消息摘要算法的一种,被广泛认可为MD5算法的继任者。它是由美国国家安全局(NSA,National Security Agency)设计,经美国国家标准与技术研究院(NIST,National Institute of Standards and Technology)发布的一系列密码散列函数。SHA算法家族目前共有SHA1、SHA-2(SHA224、SHA256、SHA384、SHA512)、SHA3(SHA3-224、SHA3-256、SHA3-384、SHA3-512等)。

SHA算法的实现方式与MD5相似,只需要在参数指定对应的算法名称即可。SHA为SHA-1的缩写。

2.1 JDK实现

public byte[] sha256jdk(String data) throws Exception {return MessageDigest.getInstance("SHA-256").digest(data.getBytes("UTF-8"));
}@Test
public void sha256jdkTest() throws Exception {final byte[] sha256_1 = sha256jdk("我是阿汤哥");final byte[] sha256_2 = sha256jdk("我是阿汤哥");assertEquals(sha256_1, sha256_2);
}

2.2 Bouncy Castle实现

public String sha256Bc(String data) throws Exception {Security.addProvider(new BouncyCastleProvider());final byte[] digest = MessageDigest.getInstance("SHA-256").digest(data.getBytes("UTF-8"));return new String(Hex.encode(digest), "UTF-8");
}@Test
public void sha256BcTest() throws Exception {final String sha256_1 = sha256bc("我是阿汤哥");final String sha256_2 = sha256bc("我是阿汤哥");System.out.println("SHA256 first  : " + sha256_1);System.out.println("SHA256 second : " + sha256_2);assertEquals(sha256_1, sha256_2);
}

2.3 Commons Codec

public String sha256Codec(String data) throws Exception {return DigestUtils.sha256Hex(data);
}@Test
public void sha256CodecTest() throws Exception {final String sha256_1 = sha256Codec("我是阿汤哥");final String sha256_2 = sha256Codec("我是阿汤哥");System.out.println("SHA256 first  : " + sha256_1);System.out.println("SHA256 second : " + sha256_2);assertEquals(sha256_1, sha256_2);
}

执行结果

SHA256 first  : 7a78507d8bf0387f52683974184252b8b41cedd6ca2373df8dec6e6e2ca219e9
SHA256 second : 7a78507d8bf0387f52683974184252b8b41cedd6ca2373df8dec6e6e2ca219e9

3. MAC

MAC(Message Authentication Code,消息认证码算法)是含有密钥散列函数算法,兼容了MD和SHA算法的特性,并在此基础上加入了密钥。因为MAC算法融合了密钥散列函数(keyed-Hash),通常我们也把MAC称为HMAC(keyed-Hash Message Authentication Code)。MAC算法和HMAC算法基本上可等同对待。

MAC算法主要集合了MD和SHA两大系列消息摘要算法。MD系列算法有HmacMD2、HmacMD4和HmacMD5三种算法;
SHA系列算法有HmacSHA1、HmacSHA224、HmacSHA256、HmacSHA384和HmacSHA512五种算法。

经MAC算法得到的摘要值也可以使用十六进制编码表示,其摘要值长度与参与实现的算法摘要值长度相同。例如,HmacSHA1算法得到的摘要长度就是SHA1算法得到的摘要长度,都是160位二进制数,换算成十六进制编码为40位。

MAC与MD和SHA的主要区别在于加入了密钥,密钥是双方事先约定的,第三方不可能知道。

3.1 JDK

JDK7支持的算法包括HmacMD5、HmacSHA1、HmacSHA256、HmacSHA384和HmacSHA512。

生成密钥

public byte[] generateKey() throws NoSuchAlgorithmException {// 初始化 key generatorfinal KeyGenerator keyGenerator = KeyGenerator.getInstance("HmacMD5");// 生成密钥final SecretKey secretKey = keyGenerator.generateKey();// 获取密钥return secretKey.getEncoded();
}

生成消息摘要

public byte[] getMessageDigist(byte[] key, byte[] message) throws NoSuchAlgorithmException, InvalidKeyException {// 还原密钥final SecretKeySpec secretKeySpec = new SecretKeySpec(key, "HmacMD5");// 实例化 Macfinal Mac mac = Mac.getInstance(secretKeySpec.getAlgorithm());// 初始化 Macmac.init(secretKeySpec);// 生成消息摘要return mac.doFinal(message);
}

3.2 Bouncy Castle

BouncyCastle作为补充,提供了HmacMD2、HmacMD4和HmacSHA224三种算法支持。
此外BouncyCastle还支持消息摘要的十六进制编码。

public byte[] generateKey() throws NoSuchAlgorithmException {// 添加BouncyCastleProvider支持Security.addProvider(new BouncyCastleProvider());// 初始化 key generatorfinal KeyGenerator keyGenerator = KeyGenerator.getInstance("HmacMD4");// 生成密钥final SecretKey secretKey = keyGenerator.generateKey();// 获取密钥return secretKey.getEncoded();
}public byte[] getMessageDigist(byte[] key, byte[] message) throws NoSuchAlgorithmException, InvalidKeyException {// 添加BouncyCastleProvider支持Security.addProvider(new BouncyCastleProvider());// 还原密钥final SecretKeySpec secretKeySpec = new SecretKeySpec(key, "HmacMD4");// 实例化 Macfinal Mac mac = Mac.getInstance(secretKeySpec.getAlgorithm());// 初始化 Macmac.init(secretKeySpec);// 生成消息摘要return mac.doFinal(message);
}@Test
public void testMac() throws NoSuchAlgorithmException, UnsupportedEncodingException, InvalidKeyException {// 获取密钥final byte[] secretKey = generateKey();// 获取消息摘要final byte[] md_1 = getMessageDigist(secretKey, "我是阿汤哥".getBytes("UTF-8"));final byte[] md_2 = getMessageDigist(secretKey, "我是阿汤哥".getBytes("UTF-8"));System.out.println(new String(Hex.encode(md_1), "UTF-8"));assertArrayEquals(md_1, md_2);
}

执行结果

9fd5f598eca3f4422c88a622b81e5e82

4. 其他消息摘要算法

除了MD、SHA和MAC这三大主流消息摘要算法外,还有一些我们不了解的消息摘要算法,包括RipeMD列、Tiger、Whirlpool和GOST3411算法。

RipeMD系列算法和MAC系列算法相结合,又产生了HmacRipeMD128和HmacRipeMD160两种算法。

Bouncy Castle对RipeMD系列算法和HmacRipeMD系列算法进行了实现。

5. 循环冗余校验算法 – CRC算法

CRC(Cyclic Redundancy Check,循环冗余校验)是可以根据数据产生简短固定位数的一种散列函数,主要用来检测或校验数据传输/保存后出现的错误。生成的散列值在传输或储存之前计算出来并且附加到数据后面。在使用数据之前,对数据的完整性做校验。一般来说,循环冗余校验的值都是32位的二进制数,以8位十六进制字符串形式表示。它是一类重要的线性分组码,编码和解码方法简单,检错和纠错能力强,在通信领域广泛地用于实现差错控制。

消息摘要算法与CRC算法同属散列函数,并且CRC算法很可能就是消息摘要算法的前身。

在JDK中CRC算法是由java.util.zip.CRC32类实现的。

6. 扩展

6.1 “挑战/响应”身份认证

HMAC的一个典型应用是用在“挑战/响应”(Challenge/Response)身份认证中,认证流程如下:
(1)先由客户端向服务器发出一个验证请求。
(2)服务器接到此请求后生成一个随机数并通过网络传输给客户端(此为挑战)。
(3)客户端将收到的随机数提供给ePass,由ePass使用该随机数与存储在ePass中的密钥进行HMAC-MD5运算并得到一个结果作为认证证据传给服务器(此为响应)。
(4)与此同时,服务器也使用该随机数与存储在服务器数据库中的该客户密钥进行HMAC-MD5运算,如果服务器的运算结果与客户端传回的响应结果相同,则认为客户端是一个合法用户。

参考

hmac
梁栋. Java加密与解密的艺术(第2版). 机械工业出版社. Kindle 版本.

这篇关于PKI - 消息摘要算法 - MD、SHA、MAC - 校验数据完整性的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/935480

相关文章

mac安装redis全过程

《mac安装redis全过程》文章内容主要介绍了如何从官网下载指定版本的Redis,以及如何在自定义目录下安装和启动Redis,还提到了如何修改Redis的密码和配置文件,以及使用RedisInsig... 目录MAC安装Redis安装启动redis 配置redis 常用命令总结mac安装redis官网下

SpringBoot 自定义消息转换器使用详解

《SpringBoot自定义消息转换器使用详解》本文详细介绍了SpringBoot消息转换器的知识,并通过案例操作演示了如何进行自定义消息转换器的定制开发和使用,感兴趣的朋友一起看看吧... 目录一、前言二、SpringBoot 内容协商介绍2.1 什么是内容协商2.2 内容协商机制深入理解2.2.1 内容

spring 参数校验Validation示例详解

《spring参数校验Validation示例详解》Spring提供了Validation工具类来实现对客户端传来的请求参数的有效校验,本文给大家介绍spring参数校验Validation示例详... 目录前言一、Validation常见的校验注解二、Validation的简单应用三、分组校验四、自定义校

不懂推荐算法也能设计推荐系统

本文以商业化应用推荐为例,告诉我们不懂推荐算法的产品,也能从产品侧出发, 设计出一款不错的推荐系统。 相信很多新手产品,看到算法二字,多是懵圈的。 什么排序算法、最短路径等都是相对传统的算法(注:传统是指科班出身的产品都会接触过)。但对于推荐算法,多数产品对着网上搜到的资源,都会无从下手。特别当某些推荐算法 和 “AI”扯上关系后,更是加大了理解的难度。 但,不了解推荐算法,就无法做推荐系

康拓展开(hash算法中会用到)

康拓展开是一个全排列到一个自然数的双射(也就是某个全排列与某个自然数一一对应) 公式: X=a[n]*(n-1)!+a[n-1]*(n-2)!+...+a[i]*(i-1)!+...+a[1]*0! 其中,a[i]为整数,并且0<=a[i]<i,1<=i<=n。(a[i]在不同应用中的含义不同); 典型应用: 计算当前排列在所有由小到大全排列中的顺序,也就是说求当前排列是第

csu 1446 Problem J Modified LCS (扩展欧几里得算法的简单应用)

这是一道扩展欧几里得算法的简单应用题,这题是在湖南多校训练赛中队友ac的一道题,在比赛之后请教了队友,然后自己把它a掉 这也是自己独自做扩展欧几里得算法的题目 题意:把题意转变下就变成了:求d1*x - d2*y = f2 - f1的解,很明显用exgcd来解 下面介绍一下exgcd的一些知识点:求ax + by = c的解 一、首先求ax + by = gcd(a,b)的解 这个

综合安防管理平台LntonAIServer视频监控汇聚抖动检测算法优势

LntonAIServer视频质量诊断功能中的抖动检测是一个专门针对视频稳定性进行分析的功能。抖动通常是指视频帧之间的不必要运动,这种运动可能是由于摄像机的移动、传输中的错误或编解码问题导致的。抖动检测对于确保视频内容的平滑性和观看体验至关重要。 优势 1. 提高图像质量 - 清晰度提升:减少抖动,提高图像的清晰度和细节表现力,使得监控画面更加真实可信。 - 细节增强:在低光条件下,抖

【数据结构】——原来排序算法搞懂这些就行,轻松拿捏

前言:快速排序的实现最重要的是找基准值,下面让我们来了解如何实现找基准值 基准值的注释:在快排的过程中,每一次我们要取一个元素作为枢纽值,以这个数字来将序列划分为两部分。 在此我们采用三数取中法,也就是取左端、中间、右端三个数,然后进行排序,将中间数作为枢纽值。 快速排序实现主框架: //快速排序 void QuickSort(int* arr, int left, int rig

poj 3974 and hdu 3068 最长回文串的O(n)解法(Manacher算法)

求一段字符串中的最长回文串。 因为数据量比较大,用原来的O(n^2)会爆。 小白上的O(n^2)解法代码:TLE啦~ #include<stdio.h>#include<string.h>const int Maxn = 1000000;char s[Maxn];int main(){char e[] = {"END"};while(scanf("%s", s) != EO

秋招最新大模型算法面试,熬夜都要肝完它

💥大家在面试大模型LLM这个板块的时候,不知道面试完会不会复盘、总结,做笔记的习惯,这份大模型算法岗面试八股笔记也帮助不少人拿到过offer ✨对于面试大模型算法工程师会有一定的帮助,都附有完整答案,熬夜也要看完,祝大家一臂之力 这份《大模型算法工程师面试题》已经上传CSDN,还有完整版的大模型 AI 学习资料,朋友们如果需要可以微信扫描下方CSDN官方认证二维码免费领取【保证100%免费