H__D  

一、密码学基本概念

  密码在我们的生活中有着重要的作用,那么密码究竟来自何方,为何会产生呢?

  密码学是网络安全、信息安全、区块链等产品的基础,常见的非对称加密、对称加密、散列函数等,都属于密码学范畴。

  密码学有数千年的历史,从最开始的替换法到如今的非对称加密算法,经历了古典密码学,近代密码学和现代密码学三个阶段。密码学不仅仅是数学家们的智慧,更是如今网络空间安全的重要基础。

二、密码学分类

 

  

三、加解密代码实现

1、凯撒加密

 1 package com.test.kaiser;
 2 
 3 /**
 4  * 凯撒加密
 5  */
 6 public class KaiserDemo {
 7     public static void main(String[] args) {
 8         // 定义原文
 9         String input = "Hello World";
10         // 把原文右移动3位
11         int key = 3;
12         String encryption = encryption(input, key);
13         System.out.println("encryption = " + encryption);
14         String decryption = decryption(encryption, key);
15         System.out.println("decryption = " + decryption);
16     }
17 
18 
19     /**
20      * 解密
21      * @param input
22      * @return
23      */
24     private static String decryption(String input, int key) {
25 
26         char[] chars = input.toCharArray();
27         StringBuilder sb = new StringBuilder();
28         for (char aChar : chars) {
29             sb.append((char)(aChar - key));
30         }
31         return sb.toString();
32     }
33 
34     /**
35      * 加密
36      * @param input
37      * @return
38      */
39     private static String encryption(String input, int key) {
40 
41         char[] chars = input.toCharArray();
42         StringBuilder sb = new StringBuilder();
43         for (char aChar : chars) {
44             sb.append((char)(aChar + key));
45         }
46         return sb.toString();
47     }
48 }

 2、对称加密

  DES

 1 package com.test.desaes;
 2 
 3 import com.sun.org.apache.xml.internal.security.utils.Base64;
 4 
 5 import javax.crypto.BadPaddingException;
 6 import javax.crypto.Cipher;
 7 import javax.crypto.IllegalBlockSizeException;
 8 import javax.crypto.NoSuchPaddingException;
 9 import javax.crypto.spec.SecretKeySpec;
10 import java.security.InvalidKeyException;
11 import java.security.NoSuchAlgorithmException;
12 
13 /**
14  * 对称加密
15  */
16 public class DesAesDemo {
17     public static void main(String[] args) throws Exception {
18         // 原文
19         String input = "Hello World";
20         // 定义key
21         // 如果使用DES加密,密钥必须是8位
22         String key = "12345678";
23         // 算法
24         String transformation = "DES";
25         // 加密类型
26         String algorithm = "DES";
27         // 加密
28         String encryptDES = encryptDES(input, key, transformation, algorithm);
29         System.out.println("encryptDES = " + encryptDES);
30         // 解密
31         String decryptDES = decryptDES(encryptDES, key, transformation, algorithm);
32         System.out.println("decryptDES = " + decryptDES);
33     }
34 
35     // 解密
36     private static String decryptDES(String input, String key, String transformation, String algorithm) throws Exception {
37         // 创建加密对象
38         Cipher cipher = Cipher.getInstance(transformation);
39         // 创建加密规则
40         // 第一个参数:表示key的字节
41         // 第二个参数:表示加密的类型
42         SecretKeySpec secretKeySpec = new SecretKeySpec(key.getBytes(), algorithm);
43         // 进行加密初始化
44         // 第一个参数表示模式:解密
45         // 第二个参数表示加密规则
46         cipher.init(Cipher.DECRYPT_MODE, secretKeySpec);
47         // 调用加密方法
48         // 参数:表示原文的字节数组
49         byte[] decode = Base64.decode(input);
50         byte[] bytes = cipher.doFinal(decode);
51 //        String encode = Base64.encode(bytes);
52 //        System.out.println("encode = " + encode);
53         return new String(bytes);
54     }
55 
56     // 加密
57     private static String encryptDES(String input, String key, String transformation, String algorithm) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException {
58         // 创建加密对象
59         Cipher cipher = Cipher.getInstance(transformation);
60         // 创建加密规则
61         // 第一个参数:表示key的字节
62         // 第二个参数:表示加密的类型
63         SecretKeySpec secretKeySpec = new SecretKeySpec(key.getBytes(), algorithm);
64         // 进行加密初始化
65         // 第一个参数表示模式:加密
66         // 第二个参数表示加密规则
67         cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec);
68         // 调用加密方法
69         // 参数:表示原文的字节数组
70         byte[] bytes = cipher.doFinal(input.getBytes());
71         String encode = Base64.encode(bytes);
72 //        System.out.println("encode = " + encode);
73         return encode;
74 
75 //        for (byte aByte : bytes) {
76 //            System.out.println("aByte = " + aByte);
77 //        }
78 //        // 打印秘文
79 //        System.out.println("bytes = " + new String(bytes));
80     }
81 }

  AES

 1 package com.test.desaes;
 2 
 3 import com.sun.org.apache.xml.internal.security.utils.Base64;
 4 
 5 import javax.crypto.BadPaddingException;
 6 import javax.crypto.Cipher;
 7 import javax.crypto.IllegalBlockSizeException;
 8 import javax.crypto.NoSuchPaddingException;
 9 import javax.crypto.spec.SecretKeySpec;
10 import java.security.InvalidKeyException;
11 import java.security.NoSuchAlgorithmException;
12 
13 /**
14  * 对称加密
15  */
16 public class AesDemo {
17     public static void main(String[] args) throws Exception {
18         // 原文
19         String input = "Hello World";
20         // 定义key
21         // 如果使用AES加密,密钥必须是16位
22         String key = "1234567812345678";
23         // 算法
24         String transformation = "AES";
25         // 加密类型
26         String algorithm = "AES";
27         // 加密
28         String encryptAES = encryptAES(input, key, transformation, algorithm);
29         System.out.println("encryptAES = " + encryptAES);
30         // 解密
31         String decryptAES = decryptAES(encryptAES, key, transformation, algorithm);
32         System.out.println("decryptAES = " + decryptAES);
33     }
34 
35     // 解密
36     private static String decryptAES(String input, String key, String transformation, String algorithm) throws Exception {
37         // 创建加密对象
38         Cipher cipher = Cipher.getInstance(transformation);
39         // 创建加密规则
40         // 第一个参数:表示key的字节
41         // 第二个参数:表示加密的类型
42         SecretKeySpec secretKeySpec = new SecretKeySpec(key.getBytes(), algorithm);
43         // 进行加密初始化
44         // 第一个参数表示模式:解密
45         // 第二个参数表示加密规则
46         cipher.init(Cipher.DECRYPT_MODE, secretKeySpec);
47         // 调用加密方法
48         // 参数:表示原文的字节数组
49         byte[] decode = Base64.decode(input);
50         byte[] bytes = cipher.doFinal(decode);
51 //        String encode = Base64.encode(bytes);
52 //        System.out.println("encode = " + encode);
53         return new String(bytes);
54     }
55 
56     // 加密
57     private static String encryptAES(String input, String key, String transformation, String algorithm) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException {
58         // 创建加密对象
59         Cipher cipher = Cipher.getInstance(transformation);
60         // 创建加密规则
61         // 第一个参数:表示key的字节
62         // 第二个参数:表示加密的类型
63         SecretKeySpec secretKeySpec = new SecretKeySpec(key.getBytes(), algorithm);
64         // 进行加密初始化
65         // 第一个参数表示模式:加密
66         // 第二个参数表示加密规则
67         cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec);
68         // 调用加密方法
69         // 参数:表示原文的字节数组
70         byte[] bytes = cipher.doFinal(input.getBytes());
71         String encode = Base64.encode(bytes);
72 //        System.out.println("encode = " + encode);
73         return encode;
74 
75 //        for (byte aByte : bytes) {
76 //            System.out.println("aByte = " + aByte);
77 //        }
78 //        // 打印秘文
79 //        System.out.println("bytes = " + new String(bytes));
80     }
81 }

3、非对称加密

  RSA

  1 package com.test.rsa;
  2 
  3 import com.sun.org.apache.xml.internal.security.utils.Base64;
  4 import com.test.utils.FileUtils;
  5 
  6 import javax.crypto.Cipher;
  7 import java.io.File;
  8 import java.security.*;
  9 import java.security.spec.PKCS8EncodedKeySpec;
 10 import java.security.spec.X509EncodedKeySpec;
 11 
 12 /**
 13  * 非对称加密
 14  */
 15 public class RSADemo {
 16     public static void main(String[] args) throws Exception {
 17 
 18         String input = "Hello World";
 19 
 20         // 加密算法
 21         String algorithm = "RSA";
 22 
 23         //生成密钥对并保存在本地文件中
 24 //        generateKeyToFile(algorithm, "test-encryption/a.pub", "test-encryption/a.pri");
 25         // 从本地文件中获取密钥
 26         PrivateKey privateKey = getPrivateKey(algorithm, "test-encryption/a.pri");
 27         PublicKey publicKey = getPublicKey(algorithm, "test-encryption/a.pub");
 28 
 29         // 私钥加密 - 公钥解密
 30         String encode = encryptRSA(input, algorithm, privateKey);
 31         System.out.println("encode = " + encode);
 32         String decode = decryptRSA(encode, algorithm, publicKey);
 33         System.out.println("decode = " + decode);
 34 
 35         // 公钥加密 - 私钥解密
 36 //        String encode = encryptRSA(input, algorithm, publicKey);
 37 //        System.out.println("encode = " + encode);
 38 //        String decode = decryptRSA(encode, algorithm, privateKey);
 39 //        System.out.println("decode = " + decode);
 40 
 41 
 42 
 43 //        // 私钥进行解密(无法解密)
 44 //        cipher.init(Cipher.DECRYPT_MODE, privateKey);
 45 //        byte[] bytes1 = cipher.doFinal(bytes);
 46 //        System.out.println("new String(bytes1) = " + new String(bytes1));
 47 
 48 //        // 公钥进行解密
 49 //        cipher.init(Cipher.DECRYPT_MODE, publicKey);
 50 //        byte[] bytes1 = cipher.doFinal(bytes);
 51 //        System.out.println("new String(bytes1) = " + new String(bytes1));
 52 
 53     }
 54 
 55     public static PublicKey getPublicKey(String algorithm, String pubPath) throws Exception {
 56         // 将文件内容转为字符串
 57         String publicKeyString = FileUtils.readFileToString(new File(pubPath));
 58         // 获取密钥工厂
 59         KeyFactory keyFactory = KeyFactory.getInstance(algorithm);
 60         // 构建密钥规范 进行Base64解码
 61         X509EncodedKeySpec keySpec = new X509EncodedKeySpec(Base64.decode(publicKeyString));
 62         // 生成公钥
 63         PublicKey publicKey = keyFactory.generatePublic(keySpec);
 64         return publicKey;
 65     }
 66 
 67     public static PrivateKey getPrivateKey(String algorithm, String priPath) throws Exception {
 68         // 将文件内容转为字符串
 69         String publicKeyString = FileUtils.readFileToString(new File(priPath));
 70         // 获取密钥工厂
 71         KeyFactory keyFactory = KeyFactory.getInstance(algorithm);
 72         // 构建密钥规范 进行Base64解码
 73         PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(Base64.decode(publicKeyString));
 74         // 生成公钥
 75         PrivateKey privateKey = keyFactory.generatePrivate(keySpec);
 76         return privateKey;
 77     }
 78 
 79     private static void generateKeyToFile(String algorithm, String pubPath, String priPath) throws Exception {
 80         // 创建密钥生成器对象
 81         KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(algorithm);
 82         // 生成密钥对象
 83         KeyPair keyPair = keyPairGenerator.generateKeyPair();
 84         // 生成密钥
 85         // 私钥
 86         PrivateKey privateKey = keyPair.getPrivate();
 87         // 公钥
 88         PublicKey publicKey = keyPair.getPublic();
 89         // 获取私钥字节数组
 90         byte[] privateKeyEncoded = privateKey.getEncoded();
 91         // 获取公钥字节数组
 92         byte[] publicKeyEncoded = publicKey.getEncoded();
 93         // 对密钥字节数组进行base64编码
 94         String privateKeyString = Base64.encode(privateKeyEncoded);
 95         String publicKeyString = Base64.encode(publicKeyEncoded);
 96 
 97         FileUtils.writeStringToFile(new File(priPath), privateKeyString);
 98         FileUtils.writeStringToFile(new File(pubPath), publicKeyString);
 99 //        // 打印私钥
100 //        System.out.println("privateKeyString = " + privateKeyString);
101 //        // 打印公钥
102 //        System.out.println("publicKeyString = " + publicKeyString);
103 
104     }
105 
106     private static String encryptRSA(String input, String algorithm, Key key) throws Exception {
107         // 创建加密对象
108         // 参数表示加密算法
109         Cipher cipher = Cipher.getInstance(algorithm);
110         // 初始化加密
111         // 第一个参数:加密的模式
112         // 第二个参数:使用私钥进行加密
113         cipher.init(Cipher.ENCRYPT_MODE, key);
114         // 私钥加密
115         byte[] bytes = cipher.doFinal(input.getBytes());
116         String encode = Base64.encode(bytes);
117         return encode;
118     }
119 
120     private static String decryptRSA(String input, String algorithm, Key key) throws Exception {
121         // 创建加密对象
122         // 参数表示加密算法
123         Cipher cipher = Cipher.getInstance(algorithm);
124         // 初始化加密
125         // 第一个参数:加密的模式
126         // 第二个参数:使用私钥进行加密
127         cipher.init(Cipher.DECRYPT_MODE, key);
128         // 密钥解密
129         byte[] decode = Base64.decode(input);
130         byte[] bytes = cipher.doFinal(decode);
131         return new String(bytes);
132     }
133 }

  工具类

 1 package com.test.utils;
 2 
 3 import java.io.*;
 4 
 5 public class FileUtils {
 6 
 7     public static String writeStringToFile(File destFile, String content) throws Exception {
 8         // 1、创建File类的对象,指明读入和写出的文件
 9 //        File srcFile = new File("hello.txt");
10 //        File destFile = new File("hello2.txt");
11 
12         // 2、创建输入流和输出流的对象
13 //        FileReader fileReader = null;
14         StringBuilder stringBuilder = new StringBuilder();
15         FileWriter fileWriter = null;
16         try {
17 //            fileReader = new FileReader(destFile);
18             fileWriter = new FileWriter(destFile);
19 
20             // 3、数据的读入和写出操作
21 //            char[] cbuf = new char[1024];
22 //            int len;
23 //            while ((len = fileReader.read(cbuf)) != -1) {
24 //                stringBuilder.append(new String(cbuf, 0, len));
25 //                fileWriter.write(cbuf, 0, len);
26 //            }
27             fileWriter.write(content);
28 
29         } catch (FileNotFoundException e) {
30             e.printStackTrace();
31         } catch (IOException e) {
32             e.printStackTrace();
33         } finally {
34 //
35             // 4、关闭流资源
36             if(fileWriter != null ){
37                 try {
38                     fileWriter.close();
39                 } catch (IOException e) {
40                     e.printStackTrace();
41                 }
42             }
43 //            if (fileReader != null) {
44 //                try {
45 //                    fileReader.close();
46 //                } catch (IOException e) {
47 //                    e.printStackTrace();
48 //                }
49 //            }
50         }
51         return stringBuilder.toString();
52     }
53 
54     public static String readFileToString(File srcFile) throws Exception {
55         // 1、创建File类的对象,指明读入和写出的文件
56 //        File srcFile = new File("hello.txt");
57 //        File destFile = new File("hello2.txt");
58 
59         // 2、创建输入流和输出流的对象
60         FileReader fileReader = null;
61         StringBuilder stringBuilder = new StringBuilder();
62 //        FileWriter fileWriter = null;
63         try {
64             fileReader = new FileReader(srcFile);
65 //            fileWriter = new FileWriter(destFile);
66 
67             // 3、数据的读入和写出操作
68             char[] cbuf = new char[1024];
69             int len;
70             while ((len = fileReader.read(cbuf)) != -1) {
71                 stringBuilder.append(new String(cbuf, 0, len));
72 //                fileWriter.write(cbuf, 0, len);
73             }
74 
75         } catch (FileNotFoundException e) {
76             e.printStackTrace();
77         } catch (IOException e) {
78             e.printStackTrace();
79         } finally {
80 //
81 //            // 4、关闭流资源
82 //            if(fileWriter != null ){
83 //                try {
84 //                    fileWriter.close();
85 //                } catch (IOException e) {
86 //                    e.printStackTrace();
87 //                }
88 //            }
89             if (fileReader != null) {
90                 try {
91                     fileReader.close();
92                 } catch (IOException e) {
93                     e.printStackTrace();
94                 }
95             }
96         }
97         return stringBuilder.toString();
98     }
99 }
FileUtils

4、消息摘要算法

 1 package com.test.digest;
 2 
 3 import java.security.MessageDigest;
 4 import java.security.NoSuchAlgorithmException;
 5 
 6 /**
 7  * 消息摘要算法,为了防止篡改
 8  */
 9 public class DigestDemo {
10     public static void main(String[] args) throws NoSuchAlgorithmException {
11         // 原文
12         String input = "Hello World";
13         //  算法
14         String algorithm = "MD5";
15         String MD5 = getDigest(input, algorithm);
16         // 使用base64进行转码
17 //        String encode = Base64.encode(digest1);
18 //        System.out.println("encode = " + encode);
19         System.out.println("MD5 = " + MD5);
20         System.out.println("MD5.length() = " + MD5.length());
21 
22         String sha1 = getDigest(input, "SHA-1");
23         System.out.println("sha1 = " + sha1);
24         System.out.println("sha1.length() = " + sha1.length());
25 
26         String sha256 = getDigest(input, "SHA-256");
27         System.out.println("sha256 = " + sha256);
28         System.out.println("sha256.length() = " + sha256.length());
29 
30         String sha512 = getDigest(input, "SHA-512");
31         System.out.println("sha512 = " + sha512);
32         System.out.println("sha512.length() = " + sha512.length());
33     }
34 
35     private static String getDigest(String input, String algorithm) throws NoSuchAlgorithmException {
36         // 创建消息摘要对象
37         MessageDigest digest = MessageDigest.getInstance(algorithm);
38         // 执行消息摘要算法
39         byte[] digest1 = digest.digest(input.getBytes());
40         System.out.println("密文的字节长度:" + digest1.length);
41         // 转16进制
42         return toHex(digest1);
43     }
44 
45     private static String toHex(byte[] input) {
46         StringBuilder sb = new StringBuilder();
47         for (byte b : input) {
48             // 转成 16进制
49             String s = Integer.toHexString(b & 0xff);
50             //System.out.println(s);
51             if (s.length() == 1){
52                 // 如果生成的字符只有一个,前面补0
53                 s = "0"+s;
54             }
55             sb.append(s);
56         }
57         System.out.println(sb.toString());
58         return sb.toString();
59     }
60 }

5、数字签名

 1 package com.test.digest;
 2 
 3 import com.sun.org.apache.xml.internal.security.utils.Base64;
 4 import com.test.rsa.RSADemo;
 5 
 6 import java.security.NoSuchAlgorithmException;
 7 import java.security.PrivateKey;
 8 import java.security.PublicKey;
 9 import java.security.Signature;
10 
11 /**
12  * 数字签名
13  */
14 public class SignatureDemo {
15     public static void main(String[] args) throws Exception {
16         String input = "Hello World";
17         // 加密算法
18         String algorithm = "RSA";
19         // 获取密钥
20         PrivateKey privateKey = RSADemo.getPrivateKey(algorithm, "test-encryption/a.pri");
21         PublicKey publicKey = RSADemo.getPublicKey(algorithm, "test-encryption/a.pub");
22         // 获取签名
23         String signature = getSignature(input, "sha256withrsa", privateKey);
24         System.out.println("signature = " + signature);
25         // 校验签名
26         boolean verify = verifySignature(input, "sha256withrsa", publicKey, signature);
27         System.out.println("verify = " + verify);
28     }
29 
30     private static boolean verifySignature(String input, String algorithm, PublicKey publicKey, String signatureData) throws Exception {
31         // 获取签名对象
32         Signature signature = Signature.getInstance(algorithm);
33         // 初始化校验
34         signature.initVerify(publicKey);
35         // 传入原文
36         signature.update(input.getBytes());
37         // 校验
38         byte[] decode = Base64.decode(signatureData.getBytes());
39         boolean verify = signature.verify(decode);
40         return verify;
41     }
42 
43     private static String getSignature(String input, String algorithm, PrivateKey privateKey) throws Exception {
44         // 获取签名对象
45         Signature signature = Signature.getInstance(algorithm);
46         // 初始化签名
47         signature.initSign(privateKey);
48         // 传入原文
49         signature.update(input.getBytes());
50         // 签名
51         byte[] sign = signature.sign();
52         // Base64编码
53         String encode = Base64.encode(sign);
54         return encode;
55     }
56 }

6、Base64说明

 1 package com.test.base64;
 2 
 3 import com.sun.org.apache.xml.internal.security.utils.Base64;
 4 
 5 public class TestBase64 {
 6     public static void main(String[] args) {
 7         // 当字节不够3个字节,需要使用 = 进行补齐
 8         // 1 表示一个字节,不够3个字节
 9         System.out.println(Base64.encode("1".getBytes()));
10         System.out.println(Base64.encode("12".getBytes()));
11         System.out.println(Base64.encode("123".getBytes()));
12     }
13 }

 

 

参考:https://blog.csdn.net/xiaotai1234/category_10362621.html

 

posted on 2022-06-05 19:19  H__D  阅读(115)  评论(0编辑  收藏  举报