三种摘要算法的简单介绍

article/2025/9/27 17:53:06

原文地址:

http://blog.csdn.net/u013991521/article/details/48193953

介绍:

消息摘要算法分为三类:

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

 

 

 

[java]  view plain  copy
  1. package com.timliu.security.message_digest;  
  2.   
  3. import java.security.MessageDigest;  
  4. import java.security.Security;  
  5.   
  6. import org.apache.commons.codec.binary.Hex;  
  7. import org.apache.commons.codec.digest.DigestUtils;  
  8. import org.bouncycastle.crypto.digests.MD2Digest;  
  9. import org.bouncycastle.crypto.digests.MD4Digest;  
  10. import org.bouncycastle.crypto.digests.MD5Digest;  
  11. import org.bouncycastle.jce.provider.BouncyCastleProvider;  
  12.   
  13. public class MD5Test {  
  14.   
  15.     public static final String src = "hello world";  
  16.   
  17.     public static void main(String[] args) {  
  18.         jdkMD5();  
  19.         jdkMD2();  
  20.   
  21.         bcMD4();  
  22.         bcMD5();  
  23.   
  24.         bc2jdkMD4();  
  25.   
  26.         ccMD5();  
  27.         ccMD2();  
  28.   
  29.     }  
  30.   
  31.     // 用jdk实现:MD5  
  32.     public static void jdkMD5() {  
  33.         try {  
  34.             MessageDigest md = MessageDigest.getInstance("MD5");// 得到MD5加密的对象  
  35.             byte[] md5Bytes = md.digest(src.getBytes());  
  36.             System.out.println("JDK MD5:" + Hex.encodeHexString(md5Bytes));// Hex.encodeHexString()将byte[]数组转换成十六进制  
  37.         } catch (Exception e) {  
  38.             e.printStackTrace();  
  39.         }  
  40.     }  
  41.   
  42.     // 用jdk实现:MD2  
  43.     public static void jdkMD2() {  
  44.         try {  
  45.             MessageDigest md = MessageDigest.getInstance("MD2");  
  46.             byte[] md2Bytes = md.digest(src.getBytes());  
  47.             System.out.println("JDK MD2:" + Hex.encodeHexString(md2Bytes));  
  48.         } catch (Exception e) {  
  49.             e.printStackTrace();  
  50.         }  
  51.     }  
  52.   
  53.     // 用bouncy castle实现:MD5  
  54.     public static void bcMD5() {  
  55.         MD5Digest digest = new MD5Digest();  
  56.         digest.update(src.getBytes(), 0, src.getBytes().length);  
  57.         byte[] md5Bytes = new byte[digest.getDigestSize()];  
  58.         digest.doFinal(md5Bytes, 0);  
  59.         System.out.println("bouncy castle MD5:"  
  60.                 + org.bouncycastle.util.encoders.Hex.toHexString(md5Bytes));  
  61.   
  62.     }  
  63.   
  64.     // 用bouncy castle实现:MD4  
  65.     public static void bcMD4() {  
  66.         MD4Digest digest = new MD4Digest();  
  67.         digest.update(src.getBytes(), 0, src.getBytes().length);  
  68.         byte[] md4Bytes = new byte[digest.getDigestSize()];  
  69.         digest.doFinal(md4Bytes, 0);  
  70.         System.out.println("bouncy castle MD4:"  
  71.                 + org.bouncycastle.util.encoders.Hex.toHexString(md4Bytes));  
  72.     }  
  73.   
  74.     // 用bouncy castle与jdk结合实现:MD4  
  75.     public static void bc2jdkMD4() {  
  76.         try {  
  77.             Security.addProvider(new BouncyCastleProvider());  
  78.             MessageDigest md = MessageDigest.getInstance("MD4");  
  79.             byte[] md4Bytes = md.digest(src.getBytes());  
  80.             System.out.println("bc and JDK MD4:"  
  81.                     + Hex.encodeHexString(md4Bytes));  
  82.         } catch (Exception e) {  
  83.             e.printStackTrace();  
  84.         }  
  85.     }  
  86.   
  87.     // 用common codes实现实现:MD5  
  88.     public static void ccMD5() {  
  89.         System.out.println("common codes MD5:"  
  90.                 + DigestUtils.md5Hex(src.getBytes()));  
  91.     }  
  92.   
  93.     // 用common codes实现实现:MD2  
  94.     public static void ccMD2() {  
  95.         System.out.println("common codes MD2:"  
  96.                 + DigestUtils.md2Hex(src.getBytes()));  
  97.     }  
  98.   
  99. }  

运行结果:

 

 

分析上边的代码:

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-256256JDK
SHA-384384JDK
SHA-512512JDK


例子:

 

 

[java]  view plain  copy
  1. package com.timliu.security.message_digest;  
  2.   
  3. import java.security.MessageDigest;  
  4. import java.security.Security;  
  5.   
  6. import org.apache.commons.codec.binary.Hex;  
  7. import org.apache.commons.codec.digest.DigestUtils;  
  8. import org.bouncycastle.crypto.Digest;  
  9. import org.bouncycastle.crypto.digests.SHA1Digest;  
  10. import org.bouncycastle.crypto.digests.SHA224Digest;  
  11. import org.bouncycastle.jce.provider.BouncyCastleProvider;  
  12.   
  13. public class SHATest {  
  14.     public static final String src = "hello world";  
  15.   
  16.     public static void main(String[] args) {  
  17.         jdkSHA1();  
  18.         bcSHA1();  
  19.         bcSHA224();  
  20.         bcSHA224b();  
  21.         ccSHA1();  
  22.   
  23.     }  
  24.   
  25.     // 用jdk实现:SHA1  
  26.     public static void jdkSHA1() {  
  27.         try {  
  28.             // SHA-1的名称就是SHA  
  29.             MessageDigest md = MessageDigest.getInstance("SHA");  
  30.             md.update(src.getBytes());  
  31.             System.out.println("jdk sha-1:" + Hex.encodeHexString(md.digest()));  
  32.   
  33.         } catch (Exception e) {  
  34.             e.printStackTrace();  
  35.         }  
  36.     }  
  37.   
  38.     // 用bouncy castle实现:SHA1  
  39.     public static void bcSHA1() {  
  40.   
  41.         Digest digest = new SHA1Digest();  
  42.         digest.update(src.getBytes(), 0, src.getBytes().length);  
  43.         byte[] sha1Bytes = new byte[digest.getDigestSize()];  
  44.         digest.doFinal(sha1Bytes, 0);  
  45.         System.out.println("bc sha-1:"  
  46.                 + org.bouncycastle.util.encoders.Hex.toHexString(sha1Bytes));  
  47.     }  
  48.   
  49.     // 用bouncy castle实现:SHA224  
  50.     public static void bcSHA224() {  
  51.   
  52.         Digest digest = new SHA224Digest();  
  53.         digest.update(src.getBytes(), 0, src.getBytes().length);  
  54.         byte[] sha224Bytes = new byte[digest.getDigestSize()];  
  55.         digest.doFinal(sha224Bytes, 0);  
  56.         System.out.println("bc sha-224:"  
  57.                 + org.bouncycastle.util.encoders.Hex.toHexString(sha224Bytes));  
  58.     }  
  59.   
  60.     // 用bouncy castle与jdk结合实现:SHA224  
  61.     public static void bcSHA224b() {  
  62.   
  63.         try {  
  64.             Security.addProvider(new BouncyCastleProvider());  
  65.             MessageDigest md = MessageDigest.getInstance("SHA224");  
  66.             md.update(src.getBytes());  
  67.             System.out.println("bc and JDK sha-224:"  
  68.                     + Hex.encodeHexString(md.digest()));  
  69.   
  70.         } catch (Exception e) {  
  71.             e.printStackTrace();  
  72.         }  
  73.     }  
  74.   
  75.     // 用common codes实现实现:SHA1  
  76.     public static void ccSHA1() {  
  77.         //byte[]数组方式  
  78.         System.out.println("common codes SHA1 - 1 :"  
  79.                 + DigestUtils.sha1Hex(src.getBytes()));  
  80.         //String方式  
  81.         System.out  
  82.                 .println("common codes SHA1 - 2 :" + DigestUtils.sha1Hex(src));  
  83.     }  
  84.   
  85. }  

运行结果:

 


 

分析上边的代码:

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
HmacMD4128Bouncy Castle
HmacMD5128JDK
HmacSHA1160JDK
HmacSHA224224Bouncy Castle
HmacSHA256256JDK
HmacSHA384384JDK
HmacSHA512512JDK

 

 

 

例子:

 

[java]  view plain  copy
  1. package com.timliu.security.message_digest;  
  2.   
  3. import javax.crypto.KeyGenerator;  
  4. import javax.crypto.Mac;  
  5. import javax.crypto.SecretKey;  
  6. import javax.crypto.spec.SecretKeySpec;  
  7.   
  8. import org.apache.commons.codec.binary.Hex;  
  9. import org.bouncycastle.crypto.digests.MD5Digest;  
  10. import org.bouncycastle.crypto.macs.HMac;  
  11. import org.bouncycastle.crypto.params.KeyParameter;  
  12.   
  13. public class HMACTest {  
  14.     public static final String src = "hello world";  
  15.   
  16.     public static void main(String[] args) {  
  17.         jdkHmacMD5();  
  18.         bcHmacMD5();  
  19.   
  20.     }  
  21.   
  22.     // 用jdk实现:  
  23.     public static void jdkHmacMD5() {  
  24.         try {  
  25.             // 初始化KeyGenerator  
  26.             KeyGenerator keyGenerator = KeyGenerator.getInstance("HmacMD5");  
  27.             // 产生密钥  
  28.             SecretKey secretKey = keyGenerator.generateKey();  
  29.             // 获取密钥  
  30.             // byte[] key = secretKey.getEncoded();  
  31.             byte[] key = Hex.decodeHex(new char[] { '1''2''3''4''5',  
  32.                     '6''7''8''9''a''b''c''d''e' });  
  33.   
  34.             // 还原密钥,HmacMD5是算法的名字  
  35.             SecretKey restoreSecretKey = new SecretKeySpec(key, "HmacMD5");  
  36.             // 实例化MAC  
  37.             Mac mac = Mac.getInstance(restoreSecretKey.getAlgorithm());  
  38.             // 初始化MAC  
  39.             mac.init(restoreSecretKey);  
  40.             // 执行消息摘要  
  41.             byte[] hmacMD5Bytes = mac.doFinal(src.getBytes());  
  42.             System.out.println("jdk hmacMD5:"  
  43.                     + Hex.encodeHexString(hmacMD5Bytes));  
  44.   
  45.         } catch (Exception e) {  
  46.             e.printStackTrace();  
  47.         }  
  48.     }  
  49.   
  50.     // 用bouncy castle实现:  
  51.     public static void bcHmacMD5() {  
  52.         HMac hmac = new HMac(new MD5Digest());  
  53.         // 必须是16进制的字符,长度必须是2的倍数  
  54.         hmac.init(new KeyParameter(org.bouncycastle.util.encoders.Hex  
  55.                 .decode("123456789abcde")));  
  56.         hmac.update(src.getBytes(), 0, src.getBytes().length);  
  57.   
  58.         // 执行摘要  
  59.         byte[] hmacMD5Bytes = new byte[hmac.getMacSize()];  
  60.         hmac.doFinal(hmacMD5Bytes, 0);  
  61.         System.out.println("bc hmacMD5:"  
  62.                 + org.bouncycastle.util.encoders.Hex.toHexString(hmacMD5Bytes));  
  63.   
  64.     }  
  65.   
  66. }  


运行结果:

 

代码分析:

使用jdk实现的方式中:

 

[java]  view plain  copy
  1. // 获取密钥  
  2. // byte[] key = secretKey.getEncoded();  
  3. byte[] key = Hex.decodeHex(new char[] { '1''2''3''4''5',  
  4.                     '6''7''8''9''a''b''c''d''e' });  

这里的第一个是getEncoded()是自己生成的。Hex.decodeHex()可以自己设定密钥的来源。

 

 

用bouncy castle实现的方式中:

 

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


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

 

 

HMAC算法的应用:


http://chatgpt.dhexx.cn/article/wu1I6ngw.shtml

相关文章

数据分析之运营篇

文章目录 1.指标体系定目标 1.1根据运营的目的,选取不同的指标类型 1.2.北极星指标 1.3 用户留存指标 2.数据分析找问题 2.1.描述分析 2.2多维分析 2.3.相关性分析 2.4.方差分析 2.5 样本检验 2.6 预测分析 3. 3A3R做决策 3.1洞察 3.2获客 3.3.活跃…

京东数据分析工程师(实习生)笔试

忙了一个星期,把最近的笔试面试记录一下。 京东前面单选多选题,后面3道编程题。小题考的很细,各种概率论统计数据库机器学习的知识点,很多都是蒙的,默默的把不会的题记下来,等再学会怎么做了以后发现蒙的都…

Python人力资源员工离职原因数据分析

本项目的数据集来源kaggle竞赛项目:HR-Analytics,自行下载即可! 1.提出问题 公司当中员工们离职的原因是什么? 什么样的员工会离职呢? 2.读取数据,理解数据 导入数据分析工具包,这次我们用seaborn库来优化我们的数据可视化图表! 读取数据 查看数据,head()方法没…

数据分析案例-电影数据分析

目录 电影数据集介绍 加载数据 数据探索和清洗 评分最多的电影 评分最高的电影 评分与年龄的关系 不同年龄段对某部电影的评分 电影数据集介绍 用户信息 #u.user #列名称 user_id,age,gender,occupation,zip_code #数据 1|24|M|technician|85711 2|53|F|other|94043 3…

数据分析岗位招聘分析

项目背景 学习实践数据分析,形成完整报告。分析目标:从行业、城市、学历、经验分析薪资及需求量分布情况 数据获取 集搜客获取拉勾【数据分析】为关键词的职位列表,根据列表职位详情地址爬取职位详情,435条记录,删除重复值后有…

数据分析的工作目标是什么

题图与内容无关,骗点击的。。。 其实这是回答我知识星球一位读者的问题,但恰好也是我现在在做的事情,所以想想,可以写一篇文章分享一下。 数据分析团队的工作方向,按照阶段分为如下目标。 1、提供准确、可靠、及时的基…

数据分析 面经(已拿到offer)

北航计算机专业(计院太卷,现考虑转向信息安全方向)本科二年级,闲来无事找份日常实习试试水 考虑数分岗也是因为楼主目前大二,专业课学习不够深入,开发技术尚不成熟,而sql、excel和数据可视化比…

数据分析笔试经典sql题解

欢迎关注微信公众号:开心数据 前言:sql是数据分析师笔试必考的考点之一,常考的题型有行列转换、联表查询,这些都比较简单,一般考的最难的就是hivesql窗口函数联表查询,普通的聚合函数每组(Group by)只返回…

滴滴出行2020数据分析面试题

目录 数据来源字段释义指标释义其他信息加载包加载数据数据预处理 问题1 订单的应答率、完单率分别是多少?2 呼叫应答时间多长?3 呼叫量最高的是哪一个小时(当地时间)?呼叫量最少的是哪一个小时(当地时间&a…

大数据分析实习生应该如何选择职业方向?

那么,大数据方向实习生到底该做些什么? Excel2013目前可以支持104万行数据,即使是这样也远远算不上大数据。 以下是华院数据整理的2015年大数据相关公司排名 看看你的公司在不在里边? 话说回来,对于一个实习生来说,让你处理Ex…

大数据分析实习生面试题库

大数据分析是一个有吸引力的领域,因为它不仅有利可图,而且您有机会从事有趣的项目,而且您总是在学习新事物。如果您想从头开始,请查看大数据分析实习生面试题库以准备面试要点。 大数据分析是一个有吸引力的领域。这是有利可图的&…

数据分析师实习岗笔试题(part1)

笔试后记,仅供参考 因为公司说不能泄露笔试题,所以我就加了点润色,但是不影响内容 限时免费:3小时 前言 笔试时间:2020年6月 笔试方式:在线笔试 笔试内容:sql语言、R语言/python、统计学相关知识 笔试时间:2小时之内 来几个励志的名人名言吧 要随时牢记在心中:决心…

【数据分析】滴滴数据分析岗实习经验

转载自:数据管道 原作者介绍:双非院校刚毕业的统计硕士,目前在滴滴工作,有8个月的数据分析实习经历,面试过10位以上数据分析实习生,最终成为了产品经理。 在原文的基础上有过删减。 两个主题 本文的主要目…

数据分析真题日刷 | 网易2018实习生招聘笔试题-数据分析实习生

上周开始实习,博客更新就缓下来了。这是十天前做的套题了,现在拾起来把它再整理整理。 网易数据分析实习生的笔试题,和校招的题目还是有部分重复的,不过难度也不小。 今日真题 网易2018实习生招聘笔试题-数据分析实习生 &#x…

数据分析——实习僧数据分析岗招聘信息分析

随着互联网技术不断完善,市场竞争日益激烈,粗放经营的企业将很难实现可持续发展。为改变这一现状,越来越多的企业开始对自身数据进行深度分析和挖掘,并以此辅助决策人员进行精细化决策管理。由此,越来越多的数据分析师应运而生。 本人初步踏入这一领域,希望对数据分析实…

分析数据分析实习岗位信息(1、数据获取)

目录 1.1 网页分析1.2 字体反扒机制1.3 构造字典1.4 创建表1.5 根据自己的需要进行修改 又到了一年一度的秋招了,由于受疫情的影响,部分公司减少了数据分析相关岗位的实习名额,为了更了解秋招的相关岗位信息,这里针对实习僧 网站…

我在滴滴数据分析岗实习了8个月

作者介绍:双非院校刚毕业的统计硕士,目前在滴滴工作,有8个月的数据分析实习经历,面试过10位以上数据分析实习生,最终成为了产品经理。 两个主题 本文的主要目标是帮助一些刚入门的同学了解互联网公司中“数据分析”岗位…

LOUVAIN——社交网络挖掘之大规模网络的社区发现算法

LOUVAIN——社交网络挖掘之大规模网络的社区发现算法 算法来源 该算法来源于文章Fast unfolding of communities in large networks,简称为Louvian。 算法原理 Louvain算法是基于模块度(Modularity)的社区发现算法,该算法在效率…

泛运筹理论初探——Louvain算法简介

图论-图论算法之Louvain 社区发现算法简介之Louvain算法 在本次文章中,我们将会介绍经典的社区发现方法,也就是Louvain算法。这种算法在社群发现等应用的效果较好,是比较经典的图挖掘类算法,在金融风控行业挖掘诈骗团伙等应用…

Louvain社区划分算法及Java语言实现

Louvain社区划分算法及Java语言实现 社区划分算法处理的对象Louvain社区发现算法全局模块度单层算法过程多层算法过程Java代码实现图实现模块度计算单层louvain实现多层louvain实现运行入口,使用方法 社区划分算法处理的对象 社区划分算法又称社区发现算法&#xf…