6.1、MD5

  • 推荐使用CC(即Commons Codec)实现
  • 虽然已被破解,但是仍旧广泛用于注册登录模块与验证下载的文件的完整性
  • 可以自己写一个注册登录模块;自己下载一个MD5加密的文件,然后通过之前编写的工具类(或者使用CC的方法)进行验证(具体的例子在《Java加密与解密艺术(第二版)中有》)

6.2、SHA

  • 推荐使用CC(即Commons Codec)实现
  • SHA1已被破解,SHA256广泛用于注册登录模块与验证下载的文件的完整性,并且SHA256在spring security中也有用到
  • 可以自己写一个注册登录模块;自己下载一个SHA加密的文件,然后通过之前编写的工具类(或者使用CC的方法)进行验证
  • MD5与SHA常常用于数字证书(这个之后会讲)的签名算法,但是SHA更常用

6.3、MAC

  • 在MD与SHA系列的算法上增加了密钥,使得安全程度成为三种方法之最

3.1、消息摘要算法:防止消息在传递过程中被篡改。

原理:任何消息经过消息摘要算法后,都会产生唯一的散列值(即“数据指纹”)(同一段消息无论经过多少次相同的消息摘要算法加密,结果都相同),所以如果消息在传送过程中被修改,那么算出来的数据指纹也与原本的消息算出来的不同了,如果没有被修改,则数据指纹是相同的。

特点:单向性(即只有加密,没有解密)

3.2、MD5(算法已被破解,应用于安全程度要求不高的情况下)

实现方式:

  • Commons Codec(“CC”,最推荐,因为封装了JDK的底层代码,并且提供了二进制字节数组向十六进制转化的方法)
  • JDK(没有提供二进制字节数组向十六进制转化的方法,想要进行转化,需要借助BC)
  • Bouncy Castle(“BC”,不推荐,实现比较复杂)

下边只列出基于CC的工具类代码,至于基于JDK的代码可以参考“《Java加密与解密的艺术(第2版)》”,基于BC的代码可参考“慕课网”

3.2.1、基于CC实现的MD5加密算法

pom.xml

1 <!-- https://mvnrepository.com/artifact/commons-codec/commons-codec -->
2 <dependency>
3 <groupId>commons-codec</groupId>
4 <artifactId>commons-codec</artifactId>
5 <version>1.10</version>
6 </dependency>

工具类

1 package com.util.md5;
2
3 import java.io.UnsupportedEncodingException;
4 import java.security.NoSuchAlgorithmException;
5 import org.apache.commons.codec.digest.DigestUtils;
6 /**
7 * 基于Commons Codec的md5算法
8 */
9 public class Md5CC {
10 private static final String ENCODING = "UTF-8";
11
12 /**
13 * MD5加密,加密后的结果为二进制字节数组
14 */
15 public static byte[] encode(String data) throws NoSuchAlgorithmException,UnsupportedEncodingException {
16 return DigestUtils.md5(data.getBytes(ENCODING));
17 }
18
19 /**
20 *MD5加密,加密后的结果为二进制字节数组,并且在这里将二进制字节数组转为了32位的16进制
21 */
22 public static String encodeMd5Hex(String data) throws NoSuchAlgorithmException,UnsupportedEncodingException {
23 return new String(DigestUtils.md5Hex(data.getBytes(ENCODING)));//这里直接使用new String(encodedByte,"UTF-8")不行
24 }
25
26 /**
27 * 测试
28 * @param args
29 * @throws UnsupportedEncodingException
30 * @throws NoSuchAlgorithmException
31 */
32 public static void main(String[] args) throws UnsupportedEncodingException, NoSuchAlgorithmException {
33
34 String data = "找一个好姑娘做老婆是我的梦 想!";
35 /*************测试encode()**************/
36 System.out.println("原文-->"+data);
37 byte[] encodedByte = Md5CC.encode(data);
38 System.out.println("加密后-->"+encodedByte);
39 byte[] encodedByte2 = Md5CC.encode(data);
40 System.out.println("加密后-->"+encodedByte2);
41 for(int i=0;i<encodedByte.length;i++){
42 System.out.println(encodedByte[i]==encodedByte2[i]);
43 }
44 /*************测试encodeMd5Hex()**************/
45 System.out.println("原文-->"+data);
46 String encodedStr = Md5CC.encodeMd5Hex(data);
47 System.out.println("加密后-->"+encodedStr);
48 String encodedStr2 = Md5CC.encodeMd5Hex(data);
49 System.out.println("加密后-->"+encodedStr2);
50 System.out.println(encodedStr.equals(encodedStr2));
51 }
52 }

jar包的引入参考第二章的第一个例子进行即可,在测试的过程中,自己去试着看看“同一个消息多次进行MD5加密后结果是不是相同”;

在encode()方法的测试中判断两个byte[]是否相等:按索引依次比较两个字节数组中的元素是否相同即可(如果使用main方法去测的话);如果使用Junit,直接使用assertArrayEquals(array1,array2)即可。

4.1、SHA

原理:消息摘要长度(可以定量为加密后的字符串的长度)越长,安全性越高

  • MD5:128位二进制摘要(32位16进制字符串)(已破解)
  • SHA1:160位二进制摘要(40位16进制字符串)(已破解)
  • SHA256:256位二进制摘要(64位16进制字符串)(常用,在spring security中也有使用到)

实现方式:

  • Commons Codec(“CC”,最推荐,因为封装了JDK的底层代码,并且提供了二进制字节数组向十六进制转化的方法)
  • JDK(没有提供二进制字节数组向十六进制转化的方法,想要进行转化,需要借助BC)
  • Bouncy Castle(“BC”,不推荐,实现比较复杂)

下边只列出基于CC的工具类代码,至于基于JDK的代码可以参考“《Java加密与解密的艺术(第2版)》”,基于BC的代码可参考“慕课网”

4.1.1、基于CC的SHA加密算法

1 package com.util.sha;
2
3 import java.io.UnsupportedEncodingException;
4 import java.security.NoSuchAlgorithmException;
5 import org.apache.commons.codec.digest.DigestUtils;
6 /**
7 * 基于Commons Codec的SHA算法
8 */
9 public class SHACC {
10 private static final String ENCODING = "UTF-8";
11
12 /**
13 * SHA加密,加密后的结果为二进制字节数组
14 */
15 public static byte[] encode(String data) throws NoSuchAlgorithmException,UnsupportedEncodingException {
16 //return DigestUtils.sha1(data.getBytes(ENCODING));//SHA-1
17 return DigestUtils.sha256(data.getBytes(ENCODING));//SHA-256
18 }
19
20 /**
21 *SHA加密,加密后的结果为二进制字节数组,并且在这里将二进制字节数组转为了16进制字符串
22 */
23 public static String encodeSHAHex(String data) throws NoSuchAlgorithmException,UnsupportedEncodingException {
24 //return new String(DigestUtils.sha1Hex(data.getBytes(ENCODING)));
25 return new String(DigestUtils.sha256Hex(data.getBytes(ENCODING)));
26 }
27
28 /**
29 * 测试
30 * @param args
31 * @throws UnsupportedEncodingException
32 * @throws NoSuchAlgorithmException
33 */
34 public static void main(String[] args) throws UnsupportedEncodingException, NoSuchAlgorithmException {
35
36 String data = "找一个好姑娘做老婆是我的梦 想!";
37 /*************测试encode()**************/
38 System.out.println("原文-->"+data);
39 byte[] encodedByte = SHACC.encode(data);
40 System.out.println("加密后-->"+encodedByte);
41 byte[] encodedByte2 = SHACC.encode(data);
42 System.out.println("加密后-->"+encodedByte2);
43 for(int i=0;i<encodedByte.length;i++){
44 System.out.println(encodedByte[i]==encodedByte2[i]);
45 }
46 /*************测试encodeSHAHex()**************/
47 System.out.println("原文-->"+data);
48 String encodedStr = SHACC.encodeSHAHex(data);
49 System.out.println("加密后-->"+encodedStr);
50 String encodedStr2 = SHACC.encodeSHAHex(data);
51 System.out.println("加密后-->"+encodedStr2);
52 System.out.println(encodedStr.equals(encodedStr2));
53 }
54 }

在我们需要采用相应的sha算法的时候,只需选用不同的函数即可(具体查询Commons Codec的API即可,链接在第五章末尾)。

jar包的引入参考第二章的第一个例子进行即可,在测试的过程中,自己去试着看看“同一个消息多次进行SHA加密后结果是不是相同”;

在encode()方法的测试中判断两个byte[]是否相等:按索引依次比较两个字节数组中的元素是否相同即可(如果使用main方法去测的话);如果使用Junit,直接使用assertArrayEquals(array1,array2)即可

5.1、mac(又称为Hmac)

原理:在md与sha系列算法的基础上加入了密钥,是三大常用的消息摘要算法中最安全的一个。

常用的mac算法:

  • HmacMD5
  • HmacSHA1
  • HmacSHA256

5.2、实现方式

  • JDK(缺少二进制字节数组转十六进制的工具,可借助CC或BC的工具类完成)
  • Commons Codec(CC,在1.10版本中加入的,其中,产生相应算法密钥的API没有找到,如果有人找到了,请和我讲一下,谢谢
  • Bouncy Castle(BC,比较麻烦,具体参考“慕课网”)

5.2.1、基于JDK实现的Hmac系列算法

 1 package com.util.mac;
2
3 import java.io.UnsupportedEncodingException;
4 import java.security.InvalidKeyException;
5 import java.security.NoSuchAlgorithmException;
6
7 import javax.crypto.KeyGenerator;
8 import javax.crypto.Mac;
9 import javax.crypto.SecretKey;
10 import javax.crypto.spec.SecretKeySpec;
11
12 import org.bouncycastle.util.encoders.Hex;
13
14 /**
15 * 基于JDK的HmacMD5算法
16 */
17 public class HmacMD5JDK {
18 private static final String ENCODING = "UTF-8";
19 private static final String ALGORITHM = "HmacMD5";//指定具体算法HmacMD5,HmacSHA1,HmacSHA256
20
21 /**
22 * 产生密钥两种方式 1)是由jdk自己来产生的,2)我们可以自己指定一个字节数组
23 * 注意:密钥是以二进制字节数组存储的
24 */
25 public static byte[] getKey() throws NoSuchAlgorithmException{
26 SecretKey key = KeyGenerator.getInstance(ALGORITHM).generateKey();
27 return key.getEncoded();
28 }
29
30 /**
31 * HmacMD5加密
32 * @param data 带加密数据
33 * @param keyByte 密钥
34 */
35 public static byte[] encode(String data, byte[] keyByte) throws NoSuchAlgorithmException,
36 InvalidKeyException,
37 IllegalStateException,
38 UnsupportedEncodingException {
39 SecretKey key = new SecretKeySpec(keyByte, ALGORITHM);//还原密钥
40 Mac mac = Mac.getInstance(key.getAlgorithm());
41 mac.init(key);//为mac实例初始化密钥
42 return mac.doFinal(data.getBytes(ENCODING));
43 }
44
45 /**
46 * HmacMD5加密,并转为16进制
47 */
48 public static String encodeHmacMD5Hex(String data, byte[] keyByte) throws NoSuchAlgorithmException,
49 UnsupportedEncodingException,
50 InvalidKeyException,
51 IllegalStateException {
52 byte[] encodedByte = encode(data, keyByte);
53 return new String(Hex.encode(encodedByte));//借助BC
54 //return new String(org.apache.commons.codec.binary.Hex.encodeHexString(encodedByte));//借助CC
55 }
56
57 /**
58 * 测试
59 * @throws IllegalStateException
60 * @throws InvalidKeyException
61 */
62 public static void main(String[] args) throws UnsupportedEncodingException,
63 NoSuchAlgorithmException,
64 InvalidKeyException,
65 IllegalStateException {
66 String data = "找一个好姑娘做老婆是我的梦 想!";
67 /*************测试encode()**************/
68 System.out.println("原文-->"+data);
69 byte[] keyByte = HmacMD5JDK.getKey();
70 byte[] encodedByte = HmacMD5JDK.encode(data, keyByte);
71 System.out.println("加密后-->"+encodedByte);
72 byte[] encodedByte2 = HmacMD5JDK.encode(data, keyByte);
73 System.out.println("加密后-->"+encodedByte2);
74 for(int i=0;i<encodedByte.length;i++){
75 System.out.println(encodedByte[i]==encodedByte2[i]);
76 }
77 /*************测试encodeHmacMD5Hex()**************/
78 System.out.println("原文-->"+data);
79 String encodedStr = HmacMD5JDK.encodeHmacMD5Hex(data, keyByte);
80 System.out.println("加密后-->"+encodedStr);
81 String encodedStr2 = HmacMD5JDK.encodeHmacMD5Hex(data, keyByte);
82 System.out.println("加密后-->"+encodedStr2);
83 System.out.println(encodedStr.equals(encodedStr2));
84 }
85 }

注意几点:

  • 产生密钥两种方式:1)直接使用JDK的类(如上边代码所示)2)自己指定字节数组(参考5.2.1)
  • 密钥是一个二进制数组,当然为了提高可读性,可以使用Base64加密后,在传递可对方
  • 在实际使用中,我们可以将密钥产生后,发送者通过安全途径(线下传递等)传给接收方。
  • 在上述的测试中,去测一下同一个消息在使用同一个密钥的情况下,多次mac后结果是否相同。
  • 想切换算法,只需要修改ALGORITHM常数即可,当然如果在实际项目中需要用到多种算法,并且需要实现平滑切换,可以采用策略模式,这个以后会再讲。

5.2.1、基于CC实现的Hmac系列算法

 1 package com.util.mac;
2
3 import java.io.UnsupportedEncodingException;
4 import java.security.InvalidKeyException;
5 import java.security.NoSuchAlgorithmException;
6
7 import org.apache.commons.codec.DecoderException;
8 import org.apache.commons.codec.binary.Hex;
9 import org.apache.commons.codec.digest.HmacUtils;
10
11 /**
12 * 基于CC的HmacMD5算法
13 */
14 public class HmacMD5CC {
15 private static final String ENCODING = "UTF-8";
16 /**
17 * 产生密钥
18 */
19 public static byte[] getKey() throws NoSuchAlgorithmException, DecoderException{
20 return Hex.decodeHex(new char[]{'a','b','c','d'});
21 }
22
23 /**
24 * HmacMD5加密
25 * @param data 带加密数据
26 * @param keyByte 密钥
27 */
28 public static byte[] encode(String data, byte[] keyByte) throws NoSuchAlgorithmException,
29 InvalidKeyException,
30 IllegalStateException,
31 UnsupportedEncodingException {
32 return HmacUtils.hmacMd5(keyByte, data.getBytes(ENCODING));
33 }
34
35 /**
36 * HmacMD5加密,并转为16进制
37 */
38 public static String encodeHmacMD5Hex(String data, byte[] keyByte) throws NoSuchAlgorithmException,
39 UnsupportedEncodingException,
40 InvalidKeyException,
41 IllegalStateException {
42 return HmacUtils.hmacMd5Hex(keyByte, data.getBytes(ENCODING));
43 }
44
45 /**
46 * 测试
47 * @throws IllegalStateException
48 * @throws InvalidKeyException
49 * @throws DecoderException
50 */
51 public static void main(String[] args) throws UnsupportedEncodingException,
52 NoSuchAlgorithmException,
53 InvalidKeyException,
54 IllegalStateException,
55 DecoderException {
56 String data = "找一个好姑娘做老婆是我的梦 想!";
57 /*************测试encode()**************/
58 System.out.println("原文-->"+data);
59 byte[] keyByte = HmacMD5CC.getKey();
60 byte[] encodedByte = HmacMD5CC.encode(data, keyByte);
61 System.out.println("加密后-->"+encodedByte);
62 byte[] encodedByte2 = HmacMD5CC.encode(data, keyByte);
63 System.out.println("加密后-->"+encodedByte2);
64 for(int i=0;i<encodedByte.length;i++){
65 System.out.println(encodedByte[i]==encodedByte2[i]);
66 }
67 /*************测试encodeHmacMD5Hex()**************/
68 System.out.println("原文-->"+data);
69 String encodedStr = HmacMD5CC.encodeHmacMD5Hex(data, keyByte);
70 System.out.println("加密后-->"+encodedStr);
71 String encodedStr2 = HmacMD5CC.encodeHmacMD5Hex(data, keyByte);
72 System.out.println("加密后-->"+encodedStr2);
73 System.out.println(encodedStr.equals(encodedStr2));
74 }
75 }

注意:

  • CC很好的封装了jdk的底层,但是CC是在1.10版本中才添加了hmac系列算法
  • 在使用中,若想切换其他算法,只需要调用不同的方法即可,具体的查看本文最下边的CC1.10的API文档链接地址
  • 其中,生成密钥在这里是自己指定了一个字节数组,具体的有CC来产生相应算法的密钥的API并没有看到,如果需要,可以自己去封装,当然,如果在CC中有相应的API,请大家和我讲一下,谢谢!

14.1、数字签名算法

特点:

  • 非对称加密算法+消息摘要算法的结合体
  • 抗否认性、认证数据来源、防止数据被篡改(具体意思与做法查看下边的过程与类比部分)
  • 私钥加密(签名)、公钥解密(验证)

过程:

1)消息发送者产生一个密钥对(私钥+公钥),然后将公钥发送给消息接收者

2)消息发送者使用消息摘要算法对原文进行加密(加密后的密文称作摘要)

3)消息发送者将上述的摘要使用私钥加密得到密文--这个过程就被称作签名处理,得到的密文就被称作签名(注意,这个签名是名词)

4)消息发送者将原文与密文发给消息接收者

5)消息接收者使用公钥对密文(即签名)进行解密,得到摘要值content1

6)消息接收者使用与消息发送者相同的消息摘要算法对原文进行加密,得到摘要值content2

7)比较content1是不是与content2相等,若相等,则说明消息没有被篡改(消息完整性),也说明消息却是来源于上述的消息发送方(因为其他人是无法伪造签名的,这就完成了“抗否认性”和“认证消息来源”)

类比:

手写签名:

  • 张三在合同上签了自己的名字,这样张三在后来想否认自己的这个合同内容时,就不行了(抗否认性)
  • 在张三签过名之后,若合同内容又发生了变化,这个时候签名就可以看做无效了
  • 当然,我们通过合同上张三的签名,我们就可以知道签名的来源是张三(认证数据来源)

常见的数字签名算法:

  • RSA(数字签名算法的经典,也是最常用的数字签名算法)
  • DSA(是后续数字签名算法的基础)
  • ECDSA(ECC+DSA的结合体,相较于其他数字签名算法,速度快,强度高,签名短,但是使用还没有RSA广泛)

14.2、RSA

常见算法:

  • MD5WithRSA(JDK6)
  • SHA1WithRSA(JDK6)
  • SHA256WithRSA(>=JDK1.6.45,Bouncy Castle-->简称BC)

注意:在《Java加密与解密(第二版)》一书中,说JDK6不支持SHA256WithRSA,但是经过我自己测试1.6.45是支持的。

实现方式:(参考上边三行)

  • JDK
  • BC

14.2.1、基于JDK6实现的MD5WithRSA或SHA1WithRSA或SHA256WithRSA算法

1 package com.uti.rsa.digital;
2
3 import java.io.UnsupportedEncodingException;
4 import java.security.InvalidKeyException;
5 import java.security.KeyFactory;
6 import java.security.KeyPair;
7 import java.security.KeyPairGenerator;
8 import java.security.NoSuchAlgorithmException;
9 import java.security.PrivateKey;
10 import java.security.PublicKey;
11 import java.security.Signature;
12 import java.security.SignatureException;
13 import java.security.spec.InvalidKeySpecException;
14 import java.security.spec.PKCS8EncodedKeySpec;
15 import java.security.spec.X509EncodedKeySpec;
16
17 import org.apache.commons.codec.binary.Base64;
18
19 /**
20 * 基于BC的RSA数字签名算法
21 */
22 public class RSACoderBC {
23 private static final String ENCODING = "UTF-8";
24 private static final String KEY_ALGORITHM = "RSA";//非对称加密密钥算法
25 private static final String SIGNATURE_ALGORITHM = "MD5withRSA";//指定数字签名算法(可以换成SHA1withRSA或SHA256withRSA)
26 private static final int KEY_SIZE = 512;//非对称密钥长度(512~1024之间的64的整数倍)
27
28 /**
29 * 生成发送方密钥对
30 */
31 public static KeyPair initKey() throws NoSuchAlgorithmException{
32 KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(KEY_ALGORITHM);//密钥对生成器
33 keyPairGenerator.initialize(KEY_SIZE);//指定密钥长度
34 KeyPair keyPair = keyPairGenerator.generateKeyPair();//生成密钥对
35 return keyPair;
36 }
37
38 /**
39 * 还原公钥
40 * @param pubKey 二进制公钥
41 */
42 public static PublicKey toPublicKey(byte[] pubKey) throws NoSuchAlgorithmException,
43 InvalidKeySpecException{
44 KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);//密钥工厂
45 return keyFactory.generatePublic(new X509EncodedKeySpec(pubKey));//还原公钥
46 }
47
48 /**
49 * 还原私钥
50 * @param priKey 二进制私钥
51 */
52 public static PrivateKey toPrivateKey(byte[] priKey) throws NoSuchAlgorithmException,
53 InvalidKeySpecException{
54 KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);//密钥工厂
55 return keyFactory.generatePrivate(new PKCS8EncodedKeySpec(priKey));//还原私钥
56 }
57
58 /**
59 * 私钥加密(签名)
60 * @param data 待加密数据
61 * @param keyByte 私钥
62 */
63 public static byte[] encryptPriKey(String data, byte[] keyByte) throws NoSuchAlgorithmException,
64 InvalidKeySpecException,
65 InvalidKeyException,
66 SignatureException,
67 UnsupportedEncodingException {
68 PrivateKey priKey = toPrivateKey(keyByte);//还原私钥
69
70 Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
71 signature.initSign(priKey);
72 signature.update(data.getBytes(ENCODING));
73
74 return signature.sign();
75 }
76
77 /**
78 * 公钥解密(验证)
79 * @param data 原文(待加密数据,也成为“待校验数据”)
80 * @param keyByte 公钥
81 * @param sign 密文(也称作“签名”)
82 */
83 public static boolean decryptPubKey(String data, byte[] keyByte, byte[] sign) throws NoSuchAlgorithmException,
84 InvalidKeySpecException,
85 InvalidKeyException,
86 SignatureException,
87 UnsupportedEncodingException {
88 PublicKey pubKey = toPublicKey(keyByte);//还原公钥
89
90 Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
91 signature.initVerify(pubKey);
92 signature.update(data.getBytes(ENCODING));
93
94 return signature.verify(sign);
95 }
96
97 /**
98 * 获取公钥
99 */
100 public static byte[] getPublicKey(KeyPair keyPair){
101 return keyPair.getPublic().getEncoded();
102 }
103
104 /**
105 * 获取私钥
106 */
107 public static byte[] getPrivateKey(KeyPair keyPair){
108 return keyPair.getPrivate().getEncoded();
109 }
110
111 /**
112 * 测试
113 */
114 public static void main(String[] args) throws NoSuchAlgorithmException,
115 InvalidKeyException,
116 InvalidKeySpecException,
117 SignatureException,
118 UnsupportedEncodingException {
119 byte[] pubKey1;//甲方公钥
120 byte[] priKey1;//甲方私钥
121
122 /*********************测试是否可以正确生成以上2个key*********************/
123 KeyPair keyPair1 = RSACoderBC.initKey();//生成甲方密钥对
124 pubKey1 = RSACoderBC.getPublicKey(keyPair1);
125 priKey1 = RSACoderBC.getPrivateKey(keyPair1);
126
127 System.out.println("甲方公钥pubKey1-->"+Base64.encodeBase64String(pubKey1)+"@@pubKey1.length-->"+pubKey1.length);
128 System.out.println("甲方私钥priKey1-->"+Base64.encodeBase64String(priKey1)+"@@priKey1.length-->"+priKey1.length);
129
130 /*********************测试甲方使用私钥加密数据向乙方发送,乙方使用公钥解密数据*********************/
131 System.out.println("甲方-->乙方");
132 String data = "找一个好姑娘啊!你好吗,孩子";
133 byte[] encodeStr = RSACoderBC.encryptPriKey(data, priKey1);//加密(签名)
134 System.out.println("甲方加密后的数据-->"+Base64.encodeBase64String(encodeStr)+"@@encodeStr.length-->"+encodeStr.length);
135 boolean decodeStr = RSACoderBC.decryptPubKey(data, pubKey1, encodeStr);
136 System.out.println("乙方检验结果-->"+decodeStr);
137 }
138 }

注意点:

  • 代码与RSA非对称加密算法(查看第十二章)基本一样,只是将其中的私钥加密与公钥解密部分的加解密算法改为签名和验证算法,当然没有“公钥加密,私钥解密”

第三章 消息摘要算法--MD5--SHA--MAC的更多相关文章

  1. 第三章 消息摘要算法--MD5

    注意:本节内容主要参考自<Java加密与解密的艺术(第2版)>第6章“验证数据完整性--消息摘要算法” 3.1.消息摘要算法:防止消息在传递过程中被篡改. 原理:任何消息经过消息摘要算法后 ...

  2. password学4——Java 加密解密之消息摘要算法(MD5 SHA MAC)

    Java 加密解密之消息摘要算法(MD5 SHA MAC) 消息摘要 消息摘要(Message Digest)又称为数字摘要(Digital Digest). 它是一个唯一相应一个消息或文本的固定长度 ...

  3. Java加密技术(一)——BASE64与单向加密算法MD5&SHA&MAC

    Java加密技术(一)——BASE64与单向加密算法MD5&SHA&MAC 博客分类: Java/Security Javabase64macmd5sha     加密解密,曾经是我一 ...

  4. 第五章 消息摘要算法--MAC

    注意:本节内容主要参考自<Java加密与解密的艺术(第2版)>第6章“验证数据完整性--消息摘要算法” 5.1.mac(又称为Hmac) 原理:在md与sha系列算法的基础上加入了密钥,是 ...

  5. 第四章 消息摘要算法--SHA

    注意:本节内容主要参考自<Java加密与解密的艺术(第2版)>第6章“验证数据完整性--消息摘要算法” 4.1.SHA 原理:消息摘要长度(可以定量为加密后的字符串的长度)越长,安全性越高 ...

  6. 信息加密之消息摘要算法的SHA

    SHA是消息摘要算法的一种实现方式,前面已经总结过MD2\4\5的实现,接下来就为大家总结一下SHA的实现. SHA的jdk实现: private static void SHA_JDK(){ try ...

  7. BASE64与单向加密算法MD5&SHA&MAC

    言归正传,这里我们主要描述Java已经实现的一些加密解密算法,最后介绍数字证书.     如基本的单向加密算法: BASE64 严格地说,属于编码格式,而非加密算法 MD5(Message Diges ...

  8. 如何生成安全的密码 Hash:MD5, SHA, PBKDF2, BCrypt 示例

    密码 Hash 值的产生是将用户所提供的密码通过使用一定的算法计算后得到的加密字符序列.在 Java 中提供很多被证明能有效保证密码安全的 Hash 算法实现,我将在这篇文章中讨论其中的部分算法. 需 ...

  9. MD、SHA、MAC消息摘要算法实现与应用

    1.消息摘要概述 消息摘要(Message Digest)又称为数字摘要(Digital Digest).它是一个唯一对应一个消息或文本的固定长度的值,它由一个单向Hash加密函数对消息进行作用而产生 ...

  10. 消息摘要算法-MAC算法系列

    一.简述 mac(Message Authentication Code,消息认证码算法)是含有密钥散列函数算法,兼容了MD和SHA算法的特性,并在此基础上加上了密钥.因此MAC算法也经常被称作HMA ...

随机推荐

  1. spring注解@PostConstruct

    该注解可以实现在运行工程时,自动运行该注解下的方法: @PostConstruct是java5的时候引入的注解,指的是在项目启动的时候执行这个方法,也可以理解为在spring容器启动的时候执行,可作为 ...

  2. UIAbility组件生命周期

    当用户打开.切换和返回到对应应用时,应用中的UIAbility实例会在其生命周期的不同状态之间转换.UIAbility类提供了一系列回调,通过这些回调可以知道当前UIAbility实例的某个状态发生改 ...

  3. 计算机网络基础/进制转换/企业级子网IP划分

    数制的含义 数制:计数的方法,指用一组固定的符号和统一的规则来表示数值的方法 数位:指数字符号在一个数中所处的位置 基数:指在某种进位计数制中,数位上所能使用的数字符号的个数 位权:指在某种进位计数制 ...

  4. .NetCore+Mysql+Vue+MVC+SqlSugar开源WMS仓库管理系统

    今天给大家推荐一个开源免费WMS仓库管理系统.仓库管理系统,可以有效控制并跟踪仓库业务的物流和成本管理全过程,实现或完善企业的仓储信息管理. 项目功能列表 基础数据 系统设置 物料管理 客户管理 供应 ...

  5. C# 请求 form-data格式的 接口 POSTMAN form-data

    HttpClient _httpClient = new HttpClient(); var postContent = new MultipartFormDataContent(); string ...

  6. Linux之buffer/cache

    buffers和cached解释 =========================================================缓存(cached)是把读取过的数据保存起来,重新读 ...

  7. Pro更改启动界面

    该方法适用于arcgispro 3.1及以上版本,我目前测试到3.3,是可以的. 使用的是pro产品的启动配置文件,利用其中的SplashScreen实现这一需求. 在bin目录下,新建(或编辑)Ar ...

  8. Fiddler模拟网络超时

    前情 最近在优化接口请求错误的报错提示,希望尽可能的能从提示语知道当前错误大致原因,于是我需要模拟各种错误请求的状况. 问题 网络超时是很常见的接口请求错误情况,在没有服务端配合的情况下,我需要怎样来 ...

  9. bluetooth_stack开源蓝牙协议栈源码分析与漏洞挖掘

    文章首发地址 https://xz.aliyun.com/t/9205 前言 网上闲逛的时候,发现github有个开源的蓝牙协议栈项目 https://github.com/sj15712795029 ...

  10. NATS: 对象存储

    https://natsbyexample.com/examples/os/intro/dotnet2 NATS 中的对象存储能力是在 Stream 之上的一种抽象,它将消息的主题视为类似键值对中的键 ...