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. pdf.js使用

    百度上很多例子,都是构建之前的! 我们使用pdf.js,最终只需要构建后的内容,大家可以通过这里进行下载: https://pan.baidu.com/s/14J-m-jeHdvn46cPhPXk54 ...

  2. centos7-arm架构yum源(armhf) yum源(中国科学技术大学)

    # CentOS-Base.repo # # The mirror system uses the connecting IP address of the client and the # upda ...

  3. 初识cuda一文通

    cuda学习博客 本文为本人cuda学习过程中的记录和理解,多参考@谭升等大佬前辈的博客,以及NVIDIA官方文档.如有错误烦请指正,如有侵权请联系删除. 0. 并行计算与计算机架构 计算机架构是并行 ...

  4. 21.Kubernetes配置默认存储类

    Kubernetes配置默认存储类 前言 今天在配置Kubesphere的时候,出现了下面的错误 经过排查,发现是这个原因 我通过下面命令,查看Kubernetes集群中的默认存储类 kubectl ...

  5. Taro首个支持鸿蒙的 UI 库,同时还兼容 React Native、小程序、H5

    Taro 4.0 已经推出一段时间了,4.0 版本主要是支持了鸿蒙端的开发以及 Vite 编译工具的支持.duxapp 在这段时间也跟随 Taro 的脚步,实现的对鸿蒙端的支持,并且也将之前的 dux ...

  6. 在使用openbms的时候发现的Thinkphp action 大小写问题

    下载了 https://gitee.com/openbms/openbms 看了看源代码,调试了一下普通用户的demo 用户 发现无法上传图片,admin不会,查看了源代码 发现是这样的 admin用 ...

  7. laravel之验证器

    开发中使用框架自带验证器进行参数验证 1.定义验证器基类,定义失败返回值 新建基础类文件 app > Http > Requests > BaseRequest.php <?p ...

  8. Django之跨域

    解决跨域请求问题可以从前端解决也可以通过配置后台解决,通过配置后台允许跨域可以解决前端的一些麻烦.Django通过中间件实现允许跨域. 1.安装django-cors-headers中间件 pip i ...

  9. 基于 C# 编写的 Visual Studio 文件编码显示与修改扩展插件

    前言 在软件开发过程中,尤其是在处理跨平台或来自不同来源的项目时,文件的编码格式往往会成为一个不可忽视的问题.不同的操作系统.编程语言和编辑器可能对文件编码有不同的支持和默认设置,这可能导致在打开一个 ...

  10. 【Amadeus原创】从域副域控无法同步的解决方法

    强制同步指令:repadmin /syncall /force 同步查询:repadmin.exe /replsummary