`
huihui920823
  • 浏览: 36893 次
  • 性别: Icon_minigender_1
  • 来自: 济南
文章分类
社区版块
存档分类
最新评论

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

阅读更多

介绍:

消息摘要算法分为三类

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&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

例子:

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

























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

分享到:
评论

相关推荐

    Java加密算法学习笔记的源码包

    有关java中Base64算法,消息摘要算法,对称加密算法,非对称加密算法,数字签名算法的使用方法相关的代码,其中包含相关的jar包

    AES加密算法学习笔记+代码

    本人学习AES加密算法所写的学习笔记,同时还包括了本人学习过程中用Python语言编写的AES加密程序,该程序不考虑效率,为了便于学习,完全按照文档描述的过程来实现,并编写了大量注释。 另外附一个从网上下载的C++...

    加密算法学习笔

    加密算法学习笔记

    AES 加密解密算法.js

    用于参数加密,api解密

    shiro学习笔记.rar

    这是shiro的学习笔记,包括学习时候自己写的代码,主要内容就是使用springboot整合shiro,实现对用户的认证和授权,以及图片验证码的实现

    CISSP学习笔记 CISSP关键知识点总结汇总.zip

    CISSP学习笔记、CISSP关键知识点总结汇总,以网上搜集到的CISSP学习资料为基础,补充修改了关键内容,不保证正确。 第一章 通过原则和策略的安全治理 第二章 人员安全和风险管理概念 第三章 业务连续性计划 第四章 ...

    Java学习笔记-个人整理的

    {1.11.1}打乱算法}{38}{subsection.1.11.1} {1.11.2}排序算法}{38}{subsection.1.11.2} {1.11.2.1}选择排序}{38}{subsubsection.1.11.2.1} {1.11.2.2}冒泡排序}{39}{subsubsection.1.11.2.2} {1.11.2.3}插入...

    java基础学习笔记全集

    java基础学习笔记全集 J2EE MVC 线程 多线程 struts 常用类的使用 spring MD5加密算法 J2EE中文教材

    daily-notes:这是我的日常笔记

    笔记LeetcodeDocker笔记Kubernetes笔记gRPCgRPC 系列gRPC系列(一)---ProtobufgRPC系列(二)---Hello gRPCgRPC系列(三)---Stream 推送流gRPC系列(四)---拦截器InterceptorgRPC系列(五)---TLS--数据加密gRPC系列(六)---...

    rust中的 Shor算法(量子模拟)_rust_代码_下载

    这个想法来自我目前学习的课程(PHYS 498 计算物理学),我们在脚本语言中实现了 Quantum Shor 算法(教授使用 python,而我使用 typescript)。一般的逻辑已经在 typescript 和(Zhaiyuqing2003/Quantum_Shor_...

    高级java笔试题-Lookoop:学习笔记

    高级java笔试题 个人博客 c++ c++primer ...基于素数的加密算法 sort (python) - 桶排序,计数排序,插入排序,快排,归并排序,冒泡排序,暴力排序 String(python) - KMP, LCS(最长公共子串),Rabin-Karp,

    [转] 大量算法下载地址

    实用性强,非理论性的算法: CSDN-算法精华(收集) 麻省理工学院《算法导论》 JAVA上加密算法的实现用例 数据结构与算法分析学习笔记 C语言常用算法源代码 遗传算法从入门到精通 ...

    l-曲线matlab代码-Notes:日常学习笔记,什么都会有w

    有关SDRAM以及DDR的工作原理学习笔记,见 2020.09.09添加 在安装了Linux的PC端构建并使用QEMU运行ARM Linux,见 2020.09.20添加 ARM汇编,学习记录 信号与系统以及DSP,学习记录 数字电路以及verilog,学习记录 2020...

    Python凯撒密码笔记:原理与实践.md

    内容摘要 本篇文章深入介绍了凯撒密码,一种基于字母替换的加密方法,通过移动字母位置来加密消息。...通过代码示例,演示了凯撒密码的加密和...最重要的是,本文的知识将为读者未来深入学习更复杂的加密算法奠定基础。

    Java 知识汇总(资源,工具,笔记,源码,文章,文档分类整理).zip

    - 【Rxjava的学习笔记】在[com.gradle.java.rxjava](/tree/master/src/main/java/com/gradle/java/rxjava)包名下; - 【LeetCode源码及题解】在[com.gradle.java.leetcode](/tree/master/src/main/java/...

    常规Java工具,算法,加密,数据库,面试题,源代码分析,解决方案.zip

    学习笔记和心得:记录了学习过程中的重点难点和心得体会,有助于学习者更好地理解和掌握知识。 二、适用人群 本资源适用于即将毕业或已经毕业,希望通过学习Java找到一份理想工作的同学。无论你是初学者还是有一定...

    【笔记】密码学与安全技术概要总结(一)

    数字摘要5.Hash攻击与防护二、加解密算法1.加解密系统基本组成2.对称加密算法3.非对称加密算法4.选择明文攻击5.混合加密机制6.离散对数与Diffie-Hellman密钥交换协议三、消息认证码与数字签名1.消息认证码2.数字签名...

    谷歌师兄的leetcode刷题笔记-THPj5-chauffe_ruby:THPj5-heater_ruby

    在这个小小的热身之后,您将学习网络安全,使用超安全加密算法(笑):移位加密. 事实上,NSA 需要加密他们的电子邮件,并希望要求您进行延迟加密。 在密码学中,移位密码,也称为凯撒密码或凯撒密码(见各种名称)...

    autosar全面学习笔记.docx

    (1) 使用加密的密钥或密钥句柄进行操作 46 (2) 尽管可能会损害应用程序安全地管理密钥 46 (3) 限制应用程序对键的访问和允许的操作 46  API扩展说明 47 2.架构 47 1.Safety概述 48 2.信息交换保护(E2E保护) 49...

    learning-with-errors-parameters:简要尝试性地分析LWE参数如何影响算法的正确性

    了解有错误学习(LWE)的参数在本笔记本中,我将简要介绍有错误学习(LWE)方法,该方法是一种量子后的公钥密码算法。 我们提供了数学背景,然后详细介绍了基于Python 3和numpy ,最后是我们的实验,其目的是了解...

Global site tag (gtag.js) - Google Analytics