001 加密

Posted juncaoit

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了001 加密相关的知识,希望对你有一定的参考价值。

  针对加密解密的算法,学了一下,首先是base64编码与解码,然后针对AES,RSA,MD5做了一个工具类,对公私密钥的生成也抽象成一个工具类,现在进行分享一下。

一:程序大纲

1.结构

  技术图片

 

二:程序

1.Base64Util

 1 package crypt.code;
 2 
 3 import org.apache.commons.codec.binary.Base64;
 4 
 5 import org.slf4j.Logger;
 6 import org.slf4j.LoggerFactory;
 7 import org.testng.annotations.Test;
 8 
 9 import java.io.UnsupportedEncodingException;
10 
11 public class Base64Util 
12     private static final Logger logger = LoggerFactory.getLogger(Base64Util.class);
13 
14     //base64 编码
15     public static String encode(byte[] bytes) 
16         return new String(Base64.encodeBase64(bytes));
17     
18     public static byte[] encodeByte(byte[] bytes)
19         return Base64.encodeBase64(bytes);
20     
21 
22     //base64 解码
23     public static String decode(byte[] bytes) 
24         return new String(Base64.decodeBase64(bytes));
25     
26     public static byte[] decode(String str)
27         return Base64.decodeBase64(str);
28     
29 
30 
31 
32     //测试
33     @Test
34     public void testCrypt() throws UnsupportedEncodingException 
35         String str = "base demo";
36         String enCode = encode(str.getBytes("utf-8"));
37         logger.info("encode:",enCode);
38 
39         String deCode = decode(enCode.getBytes("utf-8"));
40         logger.info("decode:",deCode);
41     
42 
43 

 

2.AesCryptUtil

  1 package crypt.rsa;
  2 
  3 import org.slf4j.Logger;
  4 import org.slf4j.LoggerFactory;
  5 import org.testng.annotations.Test;
  6 
  7 import javax.crypto.Cipher;
  8 import javax.crypto.KeyGenerator;
  9 import javax.crypto.SecretKey;
 10 import javax.crypto.spec.SecretKeySpec;
 11 import java.io.UnsupportedEncodingException;
 12 import java.security.SecureRandom;
 13 
 14 public class AesCryptUtil 
 15     private static final Logger logger = LoggerFactory.getLogger(AesCryptUtil.class);
 16     private static final String DEFAULT_CHARSET = "UTF-8";
 17     private static final String AES = "AES";
 18     private static String KEY = "123456";    //加密密码
 19 
 20     //对外提供的加密
 21     public static String encrypt(String str, String key) throws Exception 
 22         return doAes(str, key, Cipher.ENCRYPT_MODE);
 23     
 24 
 25     //对外提供的解密
 26     public static String decrypt(String str, String key) throws Exception 
 27         return doAes(str, key, Cipher.DECRYPT_MODE);
 28     
 29 
 30     /**
 31      * 加密与解密
 32      * @param str
 33      * @param key
 34      * @param mode
 35      * @return
 36      * @throws Exception
 37      */
 38     private static String doAes(String str,String key, int mode) throws Exception 
 39         byte[] content;
 40         //判断加解密
 41         if(Cipher.ENCRYPT_MODE == mode)
 42             //是加密
 43             content = str.getBytes(DEFAULT_CHARSET);
 44         else 
 45             content = parseHexstrToByte(str);
 46         
 47         //构造密钥生成器
 48         KeyGenerator keyGenerator = KeyGenerator.getInstance(AES);
 49         //初始化密钥生成器
 50         keyGenerator.init(128,new SecureRandom(key.getBytes()));
 51         //产生原始对称密钥
 52         SecretKey secretKey = keyGenerator.generateKey();
 53         //取货原始对此密钥的数组
 54         byte[] secretKeyByte = secretKey.getEncoded();
 55         //根据数组生成AES密钥
 56         SecretKeySpec secretKeySpec = new SecretKeySpec(secretKeyByte, AES);
 57         //根据指定算法自成密码器
 58         Cipher cipher = Cipher.getInstance(AES);
 59         //初始化密码器
 60         cipher.init(mode,secretKeySpec);
 61         byte[] result = cipher.doFinal(content);
 62         if(Cipher.ENCRYPT_MODE == mode)
 63             return parseByteToHexstr(result);
 64         else
 65             return new String(result,DEFAULT_CHARSET);
 66         
 67     
 68 
 69     /**
 70      * 二进制转为十六进制
 71      * @param result
 72      * @return
 73      */
 74     public static String parseByteToHexstr(byte[] result)
 75         StringBuilder sb = new StringBuilder();
 76         for(int i=0; i<result.length; i++)
 77             String hex = Integer.toHexString(result[i]&0xff);
 78             if(hex.length()==1)
 79                 hex = ‘0‘+hex;
 80             sb.append(hex.toUpperCase());
 81         
 82         return sb.toString();
 83     
 84 
 85     /**
 86      * 十六进制转二进制
 87      * @param hexStr
 88      * @return
 89      */
 90     public static byte[] parseHexstrToByte(String hexStr)
 91         if(hexStr.length()<1)
 92             return null;
 93         byte[] result = new byte[hexStr.length()/2];
 94         for(int i=0; i<hexStr.length()/2; i++)
 95             int high = Integer.parseInt(hexStr.substring(i*2,i*2+1),16);
 96             int low = Integer.parseInt(hexStr.substring(i*2+1,i*2+2),16);
 97             result[i] = (byte)(high*16 +low);
 98         
 99         return result;
100     
101 
102     @Test
103     public void test() throws Exception 
104         String content = "test aes";
105         String encrypt = encrypt(content, KEY);
106         logger.info("test-encrypt:",encrypt);
107         String decrypt = decrypt(encrypt, KEY);
108         logger.info("test-decrypt:",decrypt);
109     
110 
111 

 

3.生成公私密钥

 1 package crypt.rsa;
 2 
 3 import org.apache.commons.codec.binary.Base64;
 4 import org.slf4j.Logger;
 5 import org.slf4j.LoggerFactory;
 6 
 7 import java.security.KeyPair;
 8 import java.security.KeyPairGenerator;
 9 import java.security.NoSuchAlgorithmException;
10 import java.security.SecureRandom;
11 import java.security.interfaces.RSAPrivateKey;
12 import java.security.interfaces.RSAPublicKey;
13 import java.util.HashMap;
14 import java.util.Map;
15 
16 /**
17  * @Description 这个方法单独抽取出来使用
18  */
19 public class GeneKeyPair 
20     private static final Logger logger = LoggerFactory.getLogger(RsaCryptUtils.class);
21     private static Map<String,String> keyMap =new HashMap<String, String>();
22     /**
23      * 生成公私密钥
24      * @throws NoSuchAlgorithmException
25      */
26     public static void geneKeyPair() throws NoSuchAlgorithmException 
27         KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
28         //初始化密钥生成器,密钥的大小是96-1024位
29         keyPairGenerator.initialize(1024, new SecureRandom());
30         //生成一个密钥对
31         KeyPair keyPair = keyPairGenerator.generateKeyPair();
32         RSAPrivateKey privateKey = (RSAPrivateKey)keyPair.getPrivate();
33         RSAPublicKey publicKey = (RSAPublicKey)keyPair.getPublic();
34         //
35         String privateKeyStr = new String(Base64.encodeBase64(privateKey.getEncoded()));
36         String publicKeyStr = new String(Base64.encodeBase64(publicKey.getEncoded()));
37         //
38         keyMap.put("0",privateKeyStr);
39         keyMap.put("1",publicKeyStr);
40     
41 
42     /**
43      * 返回公私密钥
44      * @return
45      * @throws NoSuchAlgorithmException
46      */
47     public static Map getKey() throws NoSuchAlgorithmException 
48         geneKeyPair();
49         return keyMap;
50     
51 

 

4.Md5Util

 1 package crypt.rsa;
 2 
 3 import org.apache.commons.codec.digest.DigestUtils;
 4 import org.testng.annotations.Test;
 5 
 6 import java.security.MessageDigest;
 7 
 8 /**
 9  * @Description MD5是不可逆的,单向哈希计算
10  */
11 public class Md5Util 
12 
13     /**
14      * 方式一,使用commons-codec包
15      * @param str
16      * @return
17      */
18     public static String encrypt(String str)
19         return DigestUtils.md5Hex(str);
20     
21 
22     /**
23      * 方式二,使用MessageDigest
24      * @param str
25      * @return
26      */
27     public static String encrypt2(String str)
28         String hexStr = "";
29         try 
30             //MessageDigest 类为应用程序提供信息摘要算法的功能,如 MD5 或 SHA 算法。
31             // 信息摘要是安全的单向哈希函数,它接收任意大小的数据,并输出固定长度的哈希值。
32             MessageDigest messageDigest = MessageDigest.getInstance("MD5");
33             //完成哈希计算
34             byte[] digest = messageDigest.digest(str.getBytes("UTF-8"));
35             hexStr = AesCryptUtil.parseByteToHexstr(digest).toLowerCase();
36         catch (Exception e)
37             e.printStackTrace();
38         
39         return hexStr;
40     
41 
42     /**
43      * 测试
44      */
45     @Test
46     public void test()
47         String str = "md5 test";
48         String encrypt = encrypt(str);
49         String encrypt2 = encrypt2(str);
50         System.out.println(encrypt);
51         System.out.println(encrypt2);
52     
53 

 

5.RsaCryptUtil

 1 package crypt.rsa;
 2 
 3 import crypt.code.Base64Util;
 4 import org.apache.commons.codec.binary.Base64;
 5 import org.slf4j.Logger;
 6 import org.slf4j.LoggerFactory;
 7 import org.testng.annotations.Test;
 8 import javax.crypto.Cipher;
 9 import java.security.*;
10 import java.security.interfaces.RSAPrivateKey;
11 import java.security.interfaces.RSAPublicKey;
12 import java.security.spec.PKCS8EncodedKeySpec;
13 import java.security.spec.X509EncodedKeySpec;
14 import java.util.HashMap;
15 import java.util.Map;
16 
17 /**
18  * @Description 公钥加密,私钥解密
19  */
20 public class RsaCryptUtil 
21     private static final Logger logger = LoggerFactory.getLogger(RsaCryptUtil.class);
22     private static Map<String,String> keyMap =new HashMap<String, String>();
23 
24     /**
25      * 生成公私密钥,在实际中,可以生成一对公司公私密钥使用
26      * @throws NoSuchAlgorithmException
27      */
28     public static void geneKeyPair() throws NoSuchAlgorithmException 
29         KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
30         //初始化密钥生成器,密钥的大小是96-1024位
31         keyPairGenerator.initialize(1024, new SecureRandom());
32         //生成一个密钥对
33         KeyPair keyPair = keyPairGenerator.generateKeyPair();
34         RSAPrivateKey privateKey = (RSAPrivateKey)keyPair.getPrivate();
35         RSAPublicKey publicKey = (RSAPublicKey)keyPair.getPublic();
36         //
37         String privateKeyStr = new String(Base64.encodeBase64(privateKey.getEncoded()));
38         String publicKeyStr = new String(Base64.encodeBase64(publicKey.getEncoded()));
39         //
40         keyMap.put("0",privateKeyStr);
41         keyMap.put("1",publicKeyStr);
42     
43 
44     /**
45      * 使用公钥加密
46      * @param str
47      * @param publicKey
48      * @return
49      */
50     public static String encrypt(String str, String publicKey) throws Exception 
51         //base64编码的公钥
52         byte[] decoded = Base64.decodeBase64(publicKey);
53         RSAPublicKey pubKey = (RSAPublicKey) KeyFactory.getInstance("RSA").generatePublic(new X509EncodedKeySpec(decoded));
54         //RSA加密
55         Cipher cipher = Cipher.getInstance("RSA");
56         cipher.init(Cipher.ENCRYPT_MODE, pubKey);
57         String outStr = Base64.encodeBase64String(cipher.doFinal(str.getBytes("UTF-8")));
58         return outStr;
59     
60 
61     /**
62      * 私钥解密
63      * @param str
64      * @param privateKey
65      * @return
66      */
67     public static String decrypt(String str, String privateKey) throws Exception 
68         //对字符串进行64位解码
69         byte[] inputByte = Base64Util.decode(str);
70         //解码私钥
71         byte[] decoded = Base64Util.decode(privateKey);
72         RSAPrivateKey priKey = (RSAPrivateKey) KeyFactory.getInstance("RSA").generatePrivate(new PKCS8EncodedKeySpec(decoded));
73         //RSA解密
74         Cipher cipher = Cipher.getInstance("RSA");
75         cipher.init(Cipher.DECRYPT_MODE, priKey);
76         String outStr = new String(cipher.doFinal(inputByte));
77         return outStr;
78     
79 
80     //测试
81     @Test
82     public void test() throws Exception 
83         geneKeyPair();
84         logger.info("geneKeyPair-privateKeyStr:",keyMap.get("0"));
85         logger.info("geneKeyPair-publicKeyStr:",keyMap.get("1"));
86         //
87         String message = "crypt test demo";
88         String enMessage = encrypt(message,keyMap.get("1"));
89         logger.info("test-enMessage:",enMessage);
90         String deMessage =decrypt(enMessage,keyMap.get("0"));
91         logger.info("test-deMessage:",deMessage);
92     
93 

 

6.扩展一下RSA

 1 package crypt.rsa;
 2 
 3 import crypt.code.Base64Util;
 4 import org.apache.commons.codec.binary.Base64;
 5 import org.slf4j.Logger;
 6 import org.slf4j.LoggerFactory;
 7 import org.springframework.beans.factory.annotation.Autowired;
 8 import org.testng.annotations.Test;
 9 
10 import javax.crypto.Cipher;
11 import java.security.*;
12 import java.security.interfaces.RSAPrivateKey;
13 import java.security.interfaces.RSAPublicKey;
14 import java.security.spec.PKCS8EncodedKeySpec;
15 import java.security.spec.X509EncodedKeySpec;
16 import java.util.HashMap;
17 import java.util.Map;
18 
19 /**
20  * @Description  扩展一下,不仅仅是RsaCryptUtil的公钥加密,私钥解密
21  *                私钥加密,公钥解密
22  *                两种方法都存在使用的场合
23  */
24 public class RsaCryptUtils 
25     private static final Logger logger = LoggerFactory.getLogger(RsaCryptUtils.class);
26 
27     /**
28      * 使用私钥加密
29      * @param str
30      * @param privateKey
31      * @return
32      */
33     public static String encrypt(String str, String privateKey) throws Exception 
34         //base64编码的公钥
35         byte[] decoded = Base64.decodeBase64(privateKey);
36         RSAPrivateKey priKey = (RSAPrivateKey) KeyFactory.getInstance("RSA").generatePrivate(new PKCS8EncodedKeySpec(decoded));
37         //RSA加密
38         Cipher cipher = Cipher.getInstance("RSA");
39         cipher.init(Cipher.ENCRYPT_MODE, priKey);
40         String outStr = Base64.encodeBase64String(cipher.doFinal(str.getBytes("UTF-8")));
41         return outStr;
42     
43 
44     /**
45      * 公钥解密
46      * @param str
47      * @param publicKey
48      * @return
49      */
50     public static String decrypt(String str, String publicKey) throws Exception 
51         //对字符串进行64位解码
52         byte[] inputByte = Base64Util.decode(str);
53         //解码私钥
54         byte[] decoded = Base64Util.decode(publicKey);
55         RSAPublicKey pubKey = (RSAPublicKey) KeyFactory.getInstance("RSA").generatePublic(new X509EncodedKeySpec(decoded));
56         //RSA解密
57         Cipher cipher = Cipher.getInstance("RSA");
58         cipher.init(Cipher.DECRYPT_MODE, pubKey);
59         String outStr = new String(cipher.doFinal(inputByte));
60         return outStr;
61     
62 
63     //测试
64     @Test
65     public void test() throws Exception 
66         Map<String, String> keyMap = GeneKeyPair.getKey();
67         logger.info("geneKeyPair-privateKeyStr:",keyMap.get("0"));
68         logger.info("geneKeyPair-publicKeyStr:",keyMap.get("1"));
69         //
70         String message = "crypt test demo";
71         String enMessage = encrypt(message,keyMap.get("0"));
72         logger.info("test-enMessage:",enMessage);
73         String deMessage =decrypt(enMessage,keyMap.get("1"));
74         logger.info("test-deMessage:",deMessage);
75     
76 

 

以上是关于001 加密的主要内容,如果未能解决你的问题,请参考以下文章

23.密码学知识-加密介绍-1——2019年12月19日

在 MySQL 中加密,在 C# 中解密

PasswordBox - Free Password Vault(加密书签)

关于此实现不是 Windows 平台 FIPS 验证的加密算法的一部分。

001 shiro的架构

群英传内推第001期