原文地址:

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

运行结果:

分析上边的代码:

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

例子:

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

运行结果:

分析上边的代码:

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

算法 摘要长度 实现方
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

例子:

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

运行结果:

代码分析:

使用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算法的应用:

三种摘要算法的简单介绍相关推荐

  1. mysql锁级别_MySql三种级别锁的介绍及解锁命令

    MySql三种级别锁的介绍及解锁命令 (2014-04-29 11:59:37) 标签: 那末 用以 便能 页级的典型代表引擎为BDB. 表级的典型代表引擎为MyISAM,MEMORY和很久之前的IS ...

  2. Java处理XML的三种主流技术及介绍

    Java处理XML的三种主流技术及介绍(1) 2012-08-15 10:44 顾彬/冯晨/乔彬 IBM developerWorks 我要评论(0) 字号:T | T XML (eXtensible ...

  3. 使用Vue三种方法实现简单计算器

    使用Vue三种方法实现简单计算器 代码实现了一个简单的计算器,用户可以在输入框中输入两个数字,选择一个操作符,并点击"等于"按钮,Vue.js会根据用户的输入进行计算,并将结果显示 ...

  4. 直立车模控制中三种滤波算法简单分析(清华卓晴)

    摘自:https://mp.weixin.qq.com/s/WbCh0NFAnsf9y2blQenf7g 让我想起余义的一篇文章也是说到平衡车有三种滤波,我想和卓晴说的是一样的吧. https://b ...

  5. 怎么给视频配音?短视频作者在用的三种方法,简单易操作

    怎么给视频配音?短视频作者在用的三种方法,简单易操作 如果你也是做短视频的作者,那么相信你也一定知道,做短视频并不仅仅只是简单的拍摄剪辑发布而已,其中要做的工作还有很多,比如配音就是其中的一项.虽然并 ...

  6. Unity烘培的简单使用 三种烘焙模式的介绍

    Unity烘培的三种模式使用介绍 需要了解的知识 简介 Unity烘培是什么 间接光源和直接光源 Mixed 和 Baked 灯光设置的区别 Unity烘培在什么情况下使用 最常用的烘焙设置 Unit ...

  7. Redis三种集群模式介绍

    三种集群模式 redis有三种集群模式,其中主从是最常见的模式. Sentinel 哨兵模式是为了弥补主从复制集群中主机宕机后,主备切换的复杂性而演变出来的.哨兵顾名思义,就是用来监控的,主要作用就是 ...

  8. 用python操作浏览器的三种方式,详细介绍并附代码

    第一种:selenium导入浏览器驱动,用get方法打开浏览器,例如: import time from selenium import webdriver def mac():     driver ...

  9. 三款RPA软件简单介绍

    RPA软件是指一种可代人工处理大量基于明确规则的.重复性任务的软件,可自动执行流程任务.现在越来越多的行业使用RPA软件来释放人力,代替部分人工的工作,RPA软件也被视为企业提升效率和生产力的驱动力. ...

  10. python中if brthon环境安装包_Ant、Gradle、Python三种打包方式的介绍

    今天谈一下Androdi三种打包方式,Ant.Gradle.Python. 当然最开始打包用Ant 很方便,后来转Studio开发,自带很多Gradle插件就用了它,然后随着打包数量越多,打包时间成了 ...

最新文章

  1. android.util.AndroidRuntimeException: requestFeature() must be called before adding content
  2. Windows下Caffe的学习与应用(一)——训练自己的数据模型(GoogleNet)
  3. 【最详细】测试点分析_1051 复数乘法 (15分)_14行代码AC
  4. java 对象池 博客_Java对象池技术的原理及其实现的小结
  5. SharePoint学习札记[1] — WSS与MOSS的关系
  6. Hadoop节点热拔插
  7. 新手使用struts2,记一次struts2启动出错
  8. mongodb java驱动_Java操作MongoDB之mongodb-driver(一)
  9. Windows2003内置用户组介绍
  10. pymysql之常见数据库操作
  11. Vwmare 出现 the msi failed和解决方案
  12. SaaSpace:2022年4款最好的免费3D打印软件
  13. Vue 按照创建时间和当前时间显示(刚刚,几小时前,几天前。。。)
  14. gitgub代码汇总
  15. linux nodejs 502错误,node.js – NPM安装失败,出现502错误
  16. android 文件传输 无法复制,Win10坑死安卓!MTP连接大BUG:无法复制、丢文件
  17. IE浏览器调用jquery需要注意的小问题
  18. Linux移动光标指令hkjl,使用 HPC Pack 在 Linux VM 上執行 OpenFOAM - Azure Virtual Machines | Microsoft Docs...
  19. 前后台订单入库调用流程
  20. 前端html5学习小总结

热门文章

  1. WUSTOJ 1275: 男神的逆袭(Java)
  2. 【语义分割系列:一】DeepLab v1 / v2 论文阅读翻译笔记
  3. 手机mstsc远程工具_如何通过手机远程控制计算机
  4. error: skipping because parent directory has insecure permissions问题
  5. 魔兽TBC常用WA字符串收集
  6. windwos上外网
  7. 使用Mockito创建Mcok和Spy
  8. javacc jjtree 写法 以及 jj写法 基本语法 以及应用
  9. 《COMPLETE MAYA PRO GRAMMIN G VOLUME II》导言
  10. 如何用matlab求解多变量非线性回归,matlab多元非线性回归教程