智慧保安后台管理-外网项目备份
钟日健
2026-06-01 62eb499b0c969f246d3245d1429a97da4de1ce28
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
package org.springblade.common.utils;
 
import java.io.UnsupportedEncodingException;
import java.math.BigInteger;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.security.InvalidParameterException;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.Provider;
import java.security.SecureRandom;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import javax.crypto.Cipher;
 
import org.apache.commons.lang3.StringUtils;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.util.encoders.Hex;
 
/**
 * RSA算法加密/解密工具类。
 * 以下代码可以使用,唯一需要注意的是: org.bouncycastle...这个jar包需要找一到放到项目中,RSA所需jar包在java中已经自带了.
 *
 * @author liuyan
 */
public class RSAUtils {
    /**
     * 算法名称
     */
    private static final String ALGORITHOM = "RSA";
    /**
     * 密钥大小
     */
    private static final int KEY_SIZE = 1024;
    /**
     * 默认的安全服务提供者
     */
    private static final Provider DEFAULT_PROVIDER = new BouncyCastleProvider();
    private static KeyPairGenerator keyPairGen = null;
    private static KeyFactory keyFactory = null;
    /**
     * 缓存的密钥对。
     */
    private static KeyPair oneKeyPair = null;
 
    //密文种子, 当想更换RSA钥匙的时候,只需要修改密文种子,即可更换
    private static final String radamKey = "你自己随便写上数字或者英文即可";
 
    //类加载后进行初始化数据
    static {
        try {
            keyPairGen = KeyPairGenerator.getInstance(ALGORITHOM,
                    DEFAULT_PROVIDER);
            keyFactory = KeyFactory.getInstance(ALGORITHOM, DEFAULT_PROVIDER);
        } catch (NoSuchAlgorithmException ex) {
            ex.printStackTrace();
        }
    }
 
    /**
     * 根据指定的密文种子,生成并返回RSA密钥对。
     */
    private static synchronized KeyPair generateKeyPair() {
        try {
            keyPairGen.initialize(KEY_SIZE,
                    new SecureRandom(radamKey.getBytes()));
            oneKeyPair = keyPairGen.generateKeyPair();
            return oneKeyPair;
        } catch (InvalidParameterException ex) {
            ex.printStackTrace();
        } catch (NullPointerException ex) {
            ex.printStackTrace();
        }
        return null;
    }
 
    /**
     * 返回初始化时默认的公钥。
     */
    public static RSAPublicKey getDefaultPublicKey() {
        KeyPair keyPair = generateKeyPair();
        if (keyPair != null) {
            return (RSAPublicKey) keyPair.getPublic();
        }
        return null;
    }
 
    /**
     * 使用指定的私钥解密数据。
     *
     * @param privateKey 给定的私钥。
     * @param data       要解密的数据。
     * @return 原数据。
     */
    public static byte[] decrypt(PrivateKey privateKey, byte[] data) throws Exception {
        Cipher ci = Cipher.getInstance(ALGORITHOM, DEFAULT_PROVIDER);
        ci.init(Cipher.DECRYPT_MODE, privateKey);
        return ci.doFinal(data);
    }
 
    /**
     * 使用默认的私钥解密给定的字符串。
     * @param encryptText 密文。
     * @return 原文字符串。
     */
    public static String decryptString(String encryptText) {
        if (StringUtils.isBlank(encryptText)) {
            return null;
        }
        KeyPair keyPair = generateKeyPair();
        try {
            byte[] en_data = Hex.decode(encryptText);
            byte[] data = decrypt((RSAPrivateKey) keyPair.getPrivate(), en_data);
            return new String(data);
        } catch (NullPointerException ex) {
            ex.printStackTrace();
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return null;
    }
 
    /**
     * 使用秘钥 - 对js端传递过来密文进行解密
     *
     * @param encryptText 密文。
     * @return {@code encryptText} 的原文字符串。
     */
    public static String decryptStringByJs(String encryptText) {
        String text = decryptString(encryptText);
        if (text == null) {
            return null;
        }
        String reverse = StringUtils.reverse(text);
        String decode = null;
        try {
            //这里需要进行编码转换.注:在前端js对明文加密前需要先进行转码-可自行百度"编码转换"
            decode = URLDecoder.decode(reverse, "UTF-8");
            System.out.println("解密后文字:" + decode);
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return decode;
    }
 
    //java端 - 使用公钥进行加密
    public static byte[] encrypt(String plaintext) throws Exception {
        // 获取公钥及参数e,n
        RSAPublicKey publicKey = RSAUtils.getDefaultPublicKey();
        //获取公钥指数 e
        BigInteger e = publicKey.getPublicExponent();
        //获取公钥系数 n
        BigInteger n = publicKey.getModulus();
        //先将明文进行编码
        String encode = URLEncoder.encode(plaintext);
        // 获取明文字节数组 m
        BigInteger m = new BigInteger(encode.getBytes());
        // 进行明文加密 c
        BigInteger c = m.modPow(e, n);
        //返回密文字节数组
        return c.toByteArray();
    }
 
    //java端 - 使用私钥进行解密
    public static String decrypt(byte[] cipherText) throws Exception {
        // 读取私钥
        KeyPair keyPair = generateKeyPair();
        RSAPrivateKey prk = (RSAPrivateKey) keyPair.getPrivate();
        // 获取私钥参数-指数/系数
        BigInteger d = prk.getPrivateExponent();
        BigInteger n = prk.getModulus();
        // 读取密文
        BigInteger c = new BigInteger(cipherText);
        // 进行解密
        BigInteger m = c.modPow(d, n);
        // 解密结果-字节数组
        byte[] mt = m.toByteArray();
        //转成String,此时是乱码
        String en = new String(mt);
        //再进行编码
        String result = java.net.URLDecoder.decode(en, "UTF-8");
        //最后返回解密后得到的明文
        return result;
    }
 
 
    public static void main(String[] args) {
        /*解密js端传递过来的密文*/
        //获取公钥对象--注意:前端那边需要用到公钥系数和指数
        RSAPublicKey publicKey = RSAUtils.getDefaultPublicKey();
        //公钥-系数(n)
        System.out.println("public key modulus:" + new String(Hex.encode(publicKey.getModulus().toByteArray())));
        //公钥-指数(e1)
        System.out.println("public key exponent:" + new String(Hex.encode(publicKey.getPublicExponent().toByteArray())));
        //JS加密后的字符串
        String param = "8c49dfb92a0c8d15b0187b1eabc343a80f340962ebecc497205f83f6a4792141d4e711b6d439388ecf691df4eda2cae1e6431573b61e3f564ffe1c757e32f3e846b5983e5939ddeb28c9570001d7f208ffbaa069677d363cc73e4c78c0d508e8b0b9f6205473269bbfbc22e7fb9413be4c449520eb6cfb4fbbff4e7e189a005a";
        //解密后的字符串
        String param1 = RSAUtils.decryptStringByJs(param);
 
        /*后端的加密和解密-在加密的方法中已经使用了公钥指数和系数*/
        try {
            //加密
            byte[] param3 = encrypt("你好> @# !!# #");
            //解密
            String decrypt = RSAUtils.decrypt(param3);
            System.out.println(decrypt);
        } catch (Exception e) {
            e.printStackTrace();
        }
 
    }
}