001/**
002 * Copyright (c) 2015-2022, Michael Yang 杨福海 (fuhai999@gmail.com).
003 * <p>
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 * <p>
008 * http://www.apache.org/licenses/LICENSE-2.0
009 * <p>
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016package io.jboot.utils;
017
018import com.jfinal.kit.Base64Kit;
019
020import javax.crypto.Cipher;
021import java.nio.charset.StandardCharsets;
022import java.security.*;
023import java.security.spec.PKCS8EncodedKeySpec;
024import java.security.spec.X509EncodedKeySpec;
025import java.util.Base64;
026
027/**
028 * RSA 非对称加密工具类,对称加密请参考 DESUtil
029 */
030public class RSAUtil {
031
032
033    /**
034     * 生成key长度为 2048 的秘钥对
035     *
036     * @return
037     * @throws Exception
038     */
039    public static KeyPair getKeyPair2048() throws Exception {
040        //《2015 年加密宣言》密码指南建议,RSA 算法使用的密钥长度至少应为 2048 位。
041        return getKeyPair(2048);
042    }
043
044    /**
045     * 生成密钥对
046     *
047     * @return
048     * @throws Exception
049     */
050    public static KeyPair getKeyPair(int keysize) throws Exception {
051        KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
052        keyPairGenerator.initialize(keysize);
053        return keyPairGenerator.generateKeyPair();
054    }
055
056
057    /**
058     * 生成key长度为 2048 的秘钥对
059     *
060     * @return [publicKey, privateKey]
061     * @throws Exception
062     */
063    public static String[] getKeyPairAsBase64() throws Exception {
064        return getKeyPairAsBase64(2048);
065    }
066
067    /**
068     * 生成密钥对
069     *
070     * @return [publicKey, privateKey]
071     * @throws Exception
072     */
073    public static String[] getKeyPairAsBase64(int keysize) throws Exception {
074        KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
075        keyPairGenerator.initialize(keysize);
076        KeyPair keyPair = keyPairGenerator.generateKeyPair();
077
078        return new String[]{Base64Kit.encode(keyPair.getPublic().getEncoded())
079                , Base64Kit.encode(keyPair.getPrivate().getEncoded())};
080    }
081
082
083    /**
084     * 公钥字符串转PublicKey实例
085     *
086     * @param publicKey
087     * @return
088     * @throws Exception
089     */
090    public static PublicKey getPublicKey(String publicKey) throws Exception {
091        byte[] publicKeyBytes = Base64.getDecoder().decode(publicKey.getBytes());
092        X509EncodedKeySpec keySpec = new X509EncodedKeySpec(publicKeyBytes);
093        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
094        return keyFactory.generatePublic(keySpec);
095    }
096
097    /**
098     * 私钥字符串转PrivateKey实例
099     *
100     * @param privateKey
101     * @return
102     * @throws Exception
103     */
104    public static PrivateKey getPrivateKey(String privateKey) throws Exception {
105        byte[] privateKeyBytes = Base64.getDecoder().decode(privateKey.getBytes());
106        PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(privateKeyBytes);
107        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
108        return keyFactory.generatePrivate(keySpec);
109    }
110
111    /**
112     * 公钥加密
113     *
114     * @param content
115     * @param publicKey
116     * @return
117     * @throws Exception
118     */
119    public static byte[] encryptByPublicKey(byte[] content, PublicKey publicKey) throws Exception {
120        Cipher cipher = Cipher.getInstance("RSA");
121        cipher.init(Cipher.ENCRYPT_MODE, publicKey);
122        return cipher.doFinal(content);
123    }
124
125
126    /**
127     * 公钥加密
128     *
129     * @param content
130     * @param publicKeyBase64
131     * @return
132     * @throws Exception
133     */
134    public static byte[] encryptByPublicKey(byte[] content, String publicKeyBase64) throws Exception {
135        return encryptByPublicKey(content, getPublicKey(publicKeyBase64));
136    }
137
138
139    /**
140     * 公钥加密
141     *
142     * @param content
143     * @param publicKey
144     * @return
145     * @throws Exception
146     */
147    public static String encryptToBase64ByPublicKey(byte[] content, PublicKey publicKey) throws Exception {
148        Cipher cipher = Cipher.getInstance("RSA");
149        cipher.init(Cipher.ENCRYPT_MODE, publicKey);
150        return Base64Kit.encode(cipher.doFinal(content));
151    }
152
153
154    /**
155     * 公钥加密
156     *
157     * @param content
158     * @param publicKeyBase64
159     * @return
160     * @throws Exception
161     */
162    public static String encryptToBase64ByPublicKey(byte[] content, String publicKeyBase64) throws Exception {
163        return encryptToBase64ByPublicKey(content, getPublicKey(publicKeyBase64));
164    }
165
166
167    /**
168     * 公钥加密
169     *
170     * @param content
171     * @param publicKeyBase64
172     * @return
173     * @throws Exception
174     */
175    public static String encryptToBase64ByPublicKey(String content, String publicKeyBase64) throws Exception {
176        return encryptToBase64ByPublicKey(content.getBytes(StandardCharsets.UTF_8), getPublicKey(publicKeyBase64));
177    }
178
179
180    /**
181     * 私钥加密
182     *
183     * @param content
184     * @param privateKey
185     * @return
186     * @throws Exception
187     */
188    public static byte[] encryptByPrivateKey(byte[] content, PrivateKey privateKey) throws Exception {
189        Cipher cipher = Cipher.getInstance("RSA");
190        cipher.init(Cipher.ENCRYPT_MODE, privateKey);
191        return cipher.doFinal(content);
192    }
193
194
195    /**
196     * 私钥加密
197     *
198     * @param content
199     * @param privateKeyBase64
200     * @return
201     * @throws Exception
202     */
203    public static byte[] encryptByPrivateKey(byte[] content, String privateKeyBase64) throws Exception {
204        return encryptByPrivateKey(content, getPrivateKey(privateKeyBase64));
205    }
206
207
208    /**
209     * 私钥加密
210     *
211     * @param content
212     * @param privateKey
213     * @return
214     * @throws Exception
215     */
216    public static String encryptToBase64ByPrivateKey(byte[] content, PrivateKey privateKey) throws Exception {
217        Cipher cipher = Cipher.getInstance("RSA");
218        cipher.init(Cipher.ENCRYPT_MODE, privateKey);
219        return Base64Kit.encode(cipher.doFinal(content));
220    }
221
222
223    /**
224     * 私钥加密
225     *
226     * @param content
227     * @param privateKeyBase64
228     * @return
229     * @throws Exception
230     */
231    public static String encryptToBase64ByPrivateKey(byte[] content, String privateKeyBase64) throws Exception {
232        return encryptToBase64ByPrivateKey(content, getPrivateKey(privateKeyBase64));
233    }
234
235
236    /**
237     * 私钥加密
238     *
239     * @param content
240     * @param privateKeyBase64
241     * @return
242     * @throws Exception
243     */
244    public static String encryptToBase64ByPrivateKey(String content, String privateKeyBase64) throws Exception {
245        return encryptToBase64ByPrivateKey(content.getBytes(StandardCharsets.UTF_8), getPrivateKey(privateKeyBase64));
246    }
247
248
249    /**
250     * 私钥解密
251     *
252     * @param content
253     * @param privateKey
254     * @return
255     * @throws Exception
256     */
257    public static byte[] decryptByPrivateKey(byte[] content, PrivateKey privateKey) throws Exception {
258        Cipher cipher = Cipher.getInstance("RSA");
259        cipher.init(Cipher.DECRYPT_MODE, privateKey);
260        return cipher.doFinal(content);
261    }
262
263
264    /**
265     * 私钥解密
266     *
267     * @param content
268     * @param privateKeyBase64
269     * @return
270     * @throws Exception
271     */
272    public static byte[] decryptByPrivateKey(byte[] content, String privateKeyBase64) throws Exception {
273        Cipher cipher = Cipher.getInstance("RSA");
274        cipher.init(Cipher.DECRYPT_MODE, getPrivateKey(privateKeyBase64));
275        return cipher.doFinal(content);
276    }
277
278
279    /**
280     * 私钥解密
281     *
282     * @param base64Content
283     * @param privateKeyBase64
284     * @return
285     * @throws Exception
286     */
287    public static String decryptToStringByPrivateKey(String base64Content, String privateKeyBase64) throws Exception {
288        Cipher cipher = Cipher.getInstance("RSA");
289        cipher.init(Cipher.DECRYPT_MODE, getPrivateKey(privateKeyBase64));
290        return new String(cipher.doFinal(Base64Kit.decode(base64Content)), StandardCharsets.UTF_8);
291    }
292
293
294    /**
295     * 公钥解密
296     *
297     * @param content
298     * @param publicKey
299     * @return
300     * @throws Exception
301     */
302    public static byte[] decrypByPublicKey(byte[] content, PublicKey publicKey) throws Exception {
303        Cipher cipher = Cipher.getInstance("RSA");
304        cipher.init(Cipher.DECRYPT_MODE, publicKey);
305        return cipher.doFinal(content);
306    }
307
308
309    /**
310     * 公钥解密
311     *
312     * @param content
313     * @param publicKeyBase64
314     * @return
315     * @throws Exception
316     */
317    public static byte[] decrypByPublicKey(byte[] content, String publicKeyBase64) throws Exception {
318        Cipher cipher = Cipher.getInstance("RSA");
319        cipher.init(Cipher.DECRYPT_MODE, getPublicKey(publicKeyBase64));
320        return cipher.doFinal(content);
321    }
322
323
324    /**
325     * 公钥解密
326     *
327     * @param base64Content
328     * @param publicKeyBase64
329     * @return
330     * @throws Exception
331     */
332    public static String decryptToStringByPublicKey(String base64Content, String publicKeyBase64) throws Exception {
333        Cipher cipher = Cipher.getInstance("RSA");
334        cipher.init(Cipher.DECRYPT_MODE, getPublicKey(publicKeyBase64));
335        return new String(cipher.doFinal(Base64Kit.decode(base64Content)), StandardCharsets.UTF_8);
336    }
337
338
339}