介绍:
消息摘要算法分为三类:
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算法的应用:
版权声明:本文为博主原创文章,未经博主允许不得转载。
分享到:
相关推荐
有关java中Base64算法,消息摘要算法,对称加密算法,非对称加密算法,数字签名算法的使用方法相关的代码,其中包含相关的jar包
本人学习AES加密算法所写的学习笔记,同时还包括了本人学习过程中用Python语言编写的AES加密程序,该程序不考虑效率,为了便于学习,完全按照文档描述的过程来实现,并编写了大量注释。 另外附一个从网上下载的C++...
加密算法学习笔记
用于参数加密,api解密
这是shiro的学习笔记,包括学习时候自己写的代码,主要内容就是使用springboot整合shiro,实现对用户的认证和授权,以及图片验证码的实现
CISSP学习笔记、CISSP关键知识点总结汇总,以网上搜集到的CISSP学习资料为基础,补充修改了关键内容,不保证正确。 第一章 通过原则和策略的安全治理 第二章 人员安全和风险管理概念 第三章 业务连续性计划 第四章 ...
{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基础学习笔记全集 J2EE MVC 线程 多线程 struts 常用类的使用 spring MD5加密算法 J2EE中文教材
笔记LeetcodeDocker笔记Kubernetes笔记gRPCgRPC 系列gRPC系列(一)---ProtobufgRPC系列(二)---Hello gRPCgRPC系列(三)---Stream 推送流gRPC系列(四)---拦截器InterceptorgRPC系列(五)---TLS--数据加密gRPC系列(六)---...
这个想法来自我目前学习的课程(PHYS 498 计算物理学),我们在脚本语言中实现了 Quantum Shor 算法(教授使用 python,而我使用 typescript)。一般的逻辑已经在 typescript 和(Zhaiyuqing2003/Quantum_Shor_...
高级java笔试题 个人博客 c++ c++primer ...基于素数的加密算法 sort (python) - 桶排序,计数排序,插入排序,快排,归并排序,冒泡排序,暴力排序 String(python) - KMP, LCS(最长公共子串),Rabin-Karp,
实用性强,非理论性的算法: CSDN-算法精华(收集) 麻省理工学院《算法导论》 JAVA上加密算法的实现用例 数据结构与算法分析学习笔记 C语言常用算法源代码 遗传算法从入门到精通 ...
有关SDRAM以及DDR的工作原理学习笔记,见 2020.09.09添加 在安装了Linux的PC端构建并使用QEMU运行ARM Linux,见 2020.09.20添加 ARM汇编,学习记录 信号与系统以及DSP,学习记录 数字电路以及verilog,学习记录 2020...
内容摘要 本篇文章深入介绍了凯撒密码,一种基于字母替换的加密方法,通过移动字母位置来加密消息。...通过代码示例,演示了凯撒密码的加密和...最重要的是,本文的知识将为读者未来深入学习更复杂的加密算法奠定基础。
- 【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找到一份理想工作的同学。无论你是初学者还是有一定...
数字摘要5.Hash攻击与防护二、加解密算法1.加解密系统基本组成2.对称加密算法3.非对称加密算法4.选择明文攻击5.混合加密机制6.离散对数与Diffie-Hellman密钥交换协议三、消息认证码与数字签名1.消息认证码2.数字签名...
在这个小小的热身之后,您将学习网络安全,使用超安全加密算法(笑):移位加密. 事实上,NSA 需要加密他们的电子邮件,并希望要求您进行延迟加密。 在密码学中,移位密码,也称为凯撒密码或凯撒密码(见各种名称)...
(1) 使用加密的密钥或密钥句柄进行操作 46 (2) 尽管可能会损害应用程序安全地管理密钥 46 (3) 限制应用程序对键的访问和允许的操作 46 API扩展说明 47 2.架构 47 1.Safety概述 48 2.信息交换保护(E2E保护) 49...
了解有错误学习(LWE)的参数在本笔记本中,我将简要介绍有错误学习(LWE)方法,该方法是一种量子后的公钥密码算法。 我们提供了数学背景,然后详细介绍了基于Python 3和numpy ,最后是我们的实验,其目的是了解...