三种摘要算法的简单介绍
原文地址:
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下载的文件截成块,分块之后进行摘要,通过摘要来验证所文件的最终的完整性,如果不完整是解压不开的。
算法 | 摘要长度 | 实现方 |
MD2 | 128 | JDK |
MD4 | 128 | Bouncy Castle |
MD5 | 128 | JDK |
- 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实现:MD5
- public 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实现:MD2
- public 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实现:MD5
- public 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实现:MD4
- public 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结合实现:MD4
- public 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实现实现:MD5
- public static void ccMD5() {
- System.out.println("common codes MD5:"
- + DigestUtils.md5Hex(src.getBytes()));
- }
- // 用common codes实现实现:MD2
- public 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-1 | 160 | JDK |
SHA-224 | 224 | Bouncy Castle |
SHA-256 | 256 | JDK |
SHA-384 | 384 | JDK |
SHA-512 | 512 | JDK |
例子:
- 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实现:SHA1
- public static void jdkSHA1() {
- try {
- // SHA-1的名称就是SHA
- MessageDigest 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实现:SHA1
- public 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实现:SHA224
- public 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结合实现:SHA224
- public 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实现实现:SHA1
- public 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×tamp=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
算法 | 摘要长度 | 实现方 |
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 |
例子:
- 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 {
- // 初始化KeyGenerator
- KeyGenerator 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");
- // 实例化MAC
- Mac mac = Mac.getInstance(restoreSecretKey.getAlgorithm());
- // 初始化MAC
- mac.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算法的应用:
三种摘要算法的简单介绍相关推荐
- mysql锁级别_MySql三种级别锁的介绍及解锁命令
MySql三种级别锁的介绍及解锁命令 (2014-04-29 11:59:37) 标签: 那末 用以 便能 页级的典型代表引擎为BDB. 表级的典型代表引擎为MyISAM,MEMORY和很久之前的IS ...
- Java处理XML的三种主流技术及介绍
Java处理XML的三种主流技术及介绍(1) 2012-08-15 10:44 顾彬/冯晨/乔彬 IBM developerWorks 我要评论(0) 字号:T | T XML (eXtensible ...
- 使用Vue三种方法实现简单计算器
使用Vue三种方法实现简单计算器 代码实现了一个简单的计算器,用户可以在输入框中输入两个数字,选择一个操作符,并点击"等于"按钮,Vue.js会根据用户的输入进行计算,并将结果显示 ...
- 直立车模控制中三种滤波算法简单分析(清华卓晴)
摘自:https://mp.weixin.qq.com/s/WbCh0NFAnsf9y2blQenf7g 让我想起余义的一篇文章也是说到平衡车有三种滤波,我想和卓晴说的是一样的吧. https://b ...
- 怎么给视频配音?短视频作者在用的三种方法,简单易操作
怎么给视频配音?短视频作者在用的三种方法,简单易操作 如果你也是做短视频的作者,那么相信你也一定知道,做短视频并不仅仅只是简单的拍摄剪辑发布而已,其中要做的工作还有很多,比如配音就是其中的一项.虽然并 ...
- Unity烘培的简单使用 三种烘焙模式的介绍
Unity烘培的三种模式使用介绍 需要了解的知识 简介 Unity烘培是什么 间接光源和直接光源 Mixed 和 Baked 灯光设置的区别 Unity烘培在什么情况下使用 最常用的烘焙设置 Unit ...
- Redis三种集群模式介绍
三种集群模式 redis有三种集群模式,其中主从是最常见的模式. Sentinel 哨兵模式是为了弥补主从复制集群中主机宕机后,主备切换的复杂性而演变出来的.哨兵顾名思义,就是用来监控的,主要作用就是 ...
- 用python操作浏览器的三种方式,详细介绍并附代码
第一种:selenium导入浏览器驱动,用get方法打开浏览器,例如: import time from selenium import webdriver def mac(): driver ...
- 三款RPA软件简单介绍
RPA软件是指一种可代人工处理大量基于明确规则的.重复性任务的软件,可自动执行流程任务.现在越来越多的行业使用RPA软件来释放人力,代替部分人工的工作,RPA软件也被视为企业提升效率和生产力的驱动力. ...
- python中if brthon环境安装包_Ant、Gradle、Python三种打包方式的介绍
今天谈一下Androdi三种打包方式,Ant.Gradle.Python. 当然最开始打包用Ant 很方便,后来转Studio开发,自带很多Gradle插件就用了它,然后随着打包数量越多,打包时间成了 ...
最新文章
- android.util.AndroidRuntimeException: requestFeature() must be called before adding content
- Windows下Caffe的学习与应用(一)——训练自己的数据模型(GoogleNet)
- 【最详细】测试点分析_1051 复数乘法 (15分)_14行代码AC
- java 对象池 博客_Java对象池技术的原理及其实现的小结
- SharePoint学习札记[1] — WSS与MOSS的关系
- Hadoop节点热拔插
- 新手使用struts2,记一次struts2启动出错
- mongodb java驱动_Java操作MongoDB之mongodb-driver(一)
- Windows2003内置用户组介绍
- pymysql之常见数据库操作
- Vwmare 出现 the msi failed和解决方案
- SaaSpace:2022年4款最好的免费3D打印软件
- Vue 按照创建时间和当前时间显示(刚刚,几小时前,几天前。。。)
- gitgub代码汇总
- linux nodejs 502错误,node.js – NPM安装失败,出现502错误
- android 文件传输 无法复制,Win10坑死安卓!MTP连接大BUG:无法复制、丢文件
- IE浏览器调用jquery需要注意的小问题
- Linux移动光标指令hkjl,使用 HPC Pack 在 Linux VM 上執行 OpenFOAM - Azure Virtual Machines | Microsoft Docs...
- 前后台订单入库调用流程
- 前端html5学习小总结
热门文章
- WUSTOJ 1275: 男神的逆袭(Java)
- 【语义分割系列:一】DeepLab v1 / v2 论文阅读翻译笔记
- 手机mstsc远程工具_如何通过手机远程控制计算机
- error: skipping because parent directory has insecure permissions问题
- 魔兽TBC常用WA字符串收集
- windwos上外网
- 使用Mockito创建Mcok和Spy
- javacc jjtree 写法 以及 jj写法 基本语法 以及应用
- 《COMPLETE MAYA PRO GRAMMIN G VOLUME II》导言
- 如何用matlab求解多变量非线性回归,matlab多元非线性回归教程