消息摘要算法---加密学习笔记(二)

2024-08-20 20:38

本文主要是介绍消息摘要算法---加密学习笔记(二),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

介绍:

消息摘要算法分为三类

MD(Message Digest):消息摘要

SHA(Secure Hash Algorithm):安全散列

MAC(Message Authentication Code):消息认证码


这三类算法的主要作用:验证数据的完整性

消息摘要算法是有关于数字签名的核心算法。


MD算法:

MD算法家族:

生成的消息摘要都是128位的。

包括:MD2,MD4,MD5

从安全性上说:MD5 > MD4 > MD2

应用举例

电驴(点对点的下载工具)使用的是经过改良的MD4的算法,这种改良后的MD4算法主要是用于通过P2P下载的文件截成块,分块之后进行摘要,通过摘要来验证所文件的最终的完整性,如果不完整是解压不开的。

算法摘要长度实现方
MD2128JDK
MD4128Bouncy Castle
MD5128JDK

package com.timliu.security.message_digest;import java.security.MessageDigest;
import java.security.Security;import org.apache.commons.codec.binary.Hex;
import org.apache.commons.codec.digest.DigestUtils;
import org.bouncycastle.crypto.digests.MD2Digest;
import org.bouncycastle.crypto.digests.MD4Digest;
import org.bouncycastle.crypto.digests.MD5Digest;
import org.bouncycastle.jce.provider.BouncyCastleProvider;public class MD5Test {public static final String src = "hello world";public static void main(String[] args) {jdkMD5();jdkMD2();bcMD4();bcMD5();bc2jdkMD4();ccMD5();ccMD2();}// 用jdk实现:MD5public static void jdkMD5() {try {MessageDigest md = MessageDigest.getInstance("MD5");// 得到MD5加密的对象byte[] md5Bytes = md.digest(src.getBytes());System.out.println("JDK MD5:" + Hex.encodeHexString(md5Bytes));// Hex.encodeHexString()将byte[]数组转换成十六进制} catch (Exception e) {e.printStackTrace();}}// 用jdk实现:MD2public static void jdkMD2() {try {MessageDigest md = MessageDigest.getInstance("MD2");byte[] md2Bytes = md.digest(src.getBytes());System.out.println("JDK MD2:" + Hex.encodeHexString(md2Bytes));} catch (Exception e) {e.printStackTrace();}}// 用bouncy castle实现:MD5public 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:"+ org.bouncycastle.util.encoders.Hex.toHexString(md5Bytes));}// 用bouncy castle实现:MD4public 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:"+ org.bouncycastle.util.encoders.Hex.toHexString(md4Bytes));}// 用bouncy castle与jdk结合实现:MD4public static void bc2jdkMD4() {try {Security.addProvider(new BouncyCastleProvider());MessageDigest md = MessageDigest.getInstance("MD4");byte[] md4Bytes = md.digest(src.getBytes());System.out.println("bc and JDK MD4:"+ Hex.encodeHexString(md4Bytes));} catch (Exception e) {e.printStackTrace();}}// 用common codes实现实现:MD5public static void ccMD5() {System.out.println("common codes MD5:"+ DigestUtils.md5Hex(src.getBytes()));}// 用common codes实现实现:MD2public static void ccMD2() {System.out.println("common codes MD2:"+ DigestUtils.md2Hex(src.getBytes()));}}
运行结果:



分析上边的代码:

bouncy castle提供了MD4,MD5,MD2的实现

common codes只是对JDK中MD5,MD2的实现进行了简化

JDK提供的MD5,MD2的实现偏底层一些,缺少了相应的进制的转换。比如,将byte[]数组转换为十六进制


MD5算法的应用:



上边是简单的用户注册,登录一个系统的过程分析图。

注册时,系统会将用户的密码进行消息摘要(如MD5),然后将用户名和密码保存到数据库中。

登录时,系统会将用户输入的密码进行消息摘要(如MD5),然后将输入的用户名和加密后的密码与数据库中的进行比对,判断是否正确。


SHA算法:

介绍:

安全散列算法

固定长度摘要信息

包括:SHA-1,SHA-2(SHA-224,SHA-256,SHA-384,SHA-512)

算法摘要长度实现方
SHA-1160JDK
SHA-224224Bouncy Castle
SHA-256
256JDK
SHA-384384JDK
SHA-512512JDK

例子:

package com.timliu.security.message_digest;import java.security.MessageDigest;
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.SHA1Digest;
import org.bouncycastle.crypto.digests.SHA224Digest;
import org.bouncycastle.jce.provider.BouncyCastleProvider;public class SHATest {public static final String src = "hello world";public static void main(String[] args) {jdkSHA1();bcSHA1();bcSHA224();bcSHA224b();ccSHA1();}// 用jdk实现:SHA1public static void jdkSHA1() {try {// SHA-1的名称就是SHAMessageDigest md = MessageDigest.getInstance("SHA");md.update(src.getBytes());System.out.println("jdk sha-1:" + Hex.encodeHexString(md.digest()));} catch (Exception e) {e.printStackTrace();}}// 用bouncy castle实现:SHA1public 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);System.out.println("bc sha-1:"+ org.bouncycastle.util.encoders.Hex.toHexString(sha1Bytes));}// 用bouncy castle实现:SHA224public 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);System.out.println("bc sha-224:"+ org.bouncycastle.util.encoders.Hex.toHexString(sha224Bytes));}// 用bouncy castle与jdk结合实现:SHA224public static void bcSHA224b() {try {Security.addProvider(new BouncyCastleProvider());MessageDigest md = MessageDigest.getInstance("SHA224");md.update(src.getBytes());System.out.println("bc and JDK sha-224:"+ Hex.encodeHexString(md.digest()));} catch (Exception e) {e.printStackTrace();}}// 用common codes实现实现:SHA1public static void ccSHA1() {//byte[]数组方式System.out.println("common codes SHA1 - 1 :"+ DigestUtils.sha1Hex(src.getBytes()));//String方式System.out.println("common codes SHA1 - 2 :" + DigestUtils.sha1Hex(src));}}
运行结果:



分析上边的代码:

bouncy castle提供了所有的SHA消息摘要算法,其中SHA-224消息摘要算法是JDK中没有提供的。

common codes只是对JDK提供的SHA消息摘要算法进行了简化。


SHA算法的应用


分析上图:

第三步和第四步是发送方将已经对消息进行SHA算法处理的消息摘要和原始的消息发送给接收方,接收方对消息进行鉴别。

消息鉴别是指接收方将原始信息进行摘要,然后与接收到的摘要信息进行比对,判断接收方接收到的消息是否是发送方发送的最原始的消息。


比如QQ的联合登陆,就是使用QQ号码登陆其他的网站需要这些过程(但是这个例子不局限与SHA算法加密):

1.在消息内容中加入约定的Key(QQ会给接入方一个Key)

2.增加时间戳(QQ会约定一个消息传递的格式)

3.排序(对消息按照一定的格式进行排序(如:msg:原始消息+key+时间戳),然后对消息进行算法摘要)

4.将摘要后的信息发送给接收方

5.接收方再按照上面的规则进行操作

http://**?msg=12Hsad74mj&timestamp=1309488734

msg是经过加密的摘要消息

timestamp是时间戳


MAC算法

介绍:

HMAC(keyed-Hash Message Authentication Code):含有密钥的散列函数算法

包含了MD和SHA两个系列的消息摘要算法

HMAC只是在原有的MD和SHA算法的基础上添加了密钥。

融合了MD,SHA:

MD系列:HmacMD2,HmacMD4,HmacMD5

SHA系列:HmacSHA1,HmacSHA224,HmacSHA256,HmacSHA38

,HmacSHA512


算法摘要长度实现方
HmacMD2128Bouncy Castle
HmacMD4
128Bouncy Castle
HmacMD5
128JDK
HmacSHA1160JDK
HmacSHA224224Bouncy Castle
HmacSHA256
256JDK
HmacSHA384
384JDK
HmacSHA512
512JDK

例子:

package com.timliu.security.message_digest;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 HMACTest {public static final String src = "hello world";public static void main(String[] args) {jdkHmacMD5();bcHmacMD5();}// 用jdk实现:public static void jdkHmacMD5() {try {// 初始化KeyGeneratorKeyGenerator 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' });// 还原密钥,HmacMD5是算法的名字SecretKey restoreSecretKey = new SecretKeySpec(key, "HmacMD5");// 实例化MACMac mac = Mac.getInstance(restoreSecretKey.getAlgorithm());// 初始化MACmac.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);System.out.println("bc hmacMD5:"+ org.bouncycastle.util.encoders.Hex.toHexString(hmacMD5Bytes));}}

运行结果:


代码分析:

使用jdk实现的方式中:

// 获取密钥
// byte[] key = secretKey.getEncoded();
byte[] key = Hex.decodeHex(new char[] { '1', '2', '3', '4', '5','6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e' });
这里的第一个是getEncoded()是自己生成的。 Hex.decodeHex()可以自己设定密钥的来源。


用bouncy castle实现的方式中:

// 必须是16进制的字符,长度必须是2的倍数hmac.init(new KeyParameter(org.bouncycastle.util.encoders.Hex.decode("123456789abcde")));

这里的Hex.decode()也是自己设定的密钥的来源。注意:来源必须是16进制的字符,长度必须是2的倍数。


HMAC算法的应用:

























版权声明:本文为博主原创文章,未经博主允许不得转载。

这篇关于消息摘要算法---加密学习笔记(二)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



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

相关文章

Python中的随机森林算法与实战

《Python中的随机森林算法与实战》本文详细介绍了随机森林算法,包括其原理、实现步骤、分类和回归案例,并讨论了其优点和缺点,通过面向对象编程实现了一个简单的随机森林模型,并应用于鸢尾花分类和波士顿房... 目录1、随机森林算法概述2、随机森林的原理3、实现步骤4、分类案例:使用随机森林预测鸢尾花品种4.1

Java中的密码加密方式

《Java中的密码加密方式》文章介绍了Java中使用MD5算法对密码进行加密的方法,以及如何通过加盐和多重加密来提高密码的安全性,MD5是一种不可逆的哈希算法,适合用于存储密码,因为其输出的摘要长度固... 目录Java的密码加密方式密码加密一般的应用方式是总结Java的密码加密方式密码加密【这里采用的

使用Python制作一个PDF批量加密工具

《使用Python制作一个PDF批量加密工具》PDF批量加密‌是一种保护PDF文件安全性的方法,通过为多个PDF文件设置相同的密码,防止未经授权的用户访问这些文件,下面我们来看看如何使用Python制... 目录1.简介2.运行效果3.相关源码1.简介一个python写的PDF批量加密工具。PDF批量加密

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

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

HarmonyOS学习(七)——UI(五)常用布局总结

自适应布局 1.1、线性布局(LinearLayout) 通过线性容器Row和Column实现线性布局。Column容器内的子组件按照垂直方向排列,Row组件中的子组件按照水平方向排列。 属性说明space通过space参数设置主轴上子组件的间距,达到各子组件在排列上的等间距效果alignItems设置子组件在交叉轴上的对齐方式,且在各类尺寸屏幕上表现一致,其中交叉轴为垂直时,取值为Vert

Ilya-AI分享的他在OpenAI学习到的15个提示工程技巧

Ilya(不是本人,claude AI)在社交媒体上分享了他在OpenAI学习到的15个Prompt撰写技巧。 以下是详细的内容: 提示精确化:在编写提示时,力求表达清晰准确。清楚地阐述任务需求和概念定义至关重要。例:不用"分析文本",而用"判断这段话的情感倾向:积极、消极还是中性"。 快速迭代:善于快速连续调整提示。熟练的提示工程师能够灵活地进行多轮优化。例:从"总结文章"到"用

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

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

【前端学习】AntV G6-08 深入图形与图形分组、自定义节点、节点动画(下)

【课程链接】 AntV G6:深入图形与图形分组、自定义节点、节点动画(下)_哔哩哔哩_bilibili 本章十吾老师讲解了一个复杂的自定义节点中,应该怎样去计算和绘制图形,如何给一个图形制作不间断的动画,以及在鼠标事件之后产生动画。(有点难,需要好好理解) <!DOCTYPE html><html><head><meta charset="UTF-8"><title>06

学习hash总结

2014/1/29/   最近刚开始学hash,名字很陌生,但是hash的思想却很熟悉,以前早就做过此类的题,但是不知道这就是hash思想而已,说白了hash就是一个映射,往往灵活利用数组的下标来实现算法,hash的作用:1、判重;2、统计次数;

康拓展开(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]在不同应用中的含义不同); 典型应用: 计算当前排列在所有由小到大全排列中的顺序,也就是说求当前排列是第