155 lines
6.7 KiB
Java
Raw Normal View History

2024-05-11 16:40:25 +08:00
package com.sf.vertx.security;
2024-05-24 18:54:30 +08:00
import java.io.ByteArrayOutputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;
2024-05-11 16:40:25 +08:00
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
2024-05-24 18:54:30 +08:00
import java.security.SecureRandom;
2024-05-11 16:40:25 +08:00
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.HashMap;
import java.util.Map;
import javax.crypto.Cipher;
2024-05-24 18:54:30 +08:00
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.lang3.ArrayUtils;
2024-05-11 16:40:25 +08:00
import lombok.extern.slf4j.Slf4j;
@Slf4j
public class RSAUtil {
// RSA最大加密明文大小
private static final int MAX_ENCRYPT_BLOCK = 117;
// RSA最大解密密文大小
private static final int MAX_DECRYPT_BLOCK = 128;
private RSAUtil() {
}
/**
* 获取公钥和私钥对key为公钥value为私钥
*
* @return
* @throws NoSuchAlgorithmException
*/
public static Map<String, String> genKeyPair() throws NoSuchAlgorithmException {
KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA");
keyPairGen.initialize(1024, new SecureRandom());
KeyPair keyPair = keyPairGen.generateKeyPair();
RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
String publicKeyString = null;
String privateKeyString = null;
try {
publicKeyString = new String(Base64.encodeBase64(publicKey.getEncoded()), "UTF-8");
privateKeyString = new String(Base64.encodeBase64(privateKey.getEncoded()), "UTF-8");
} catch (UnsupportedEncodingException var7) {
var7.printStackTrace();
}
Map<String, String> keyPairMap = new HashMap<>();
keyPairMap.put("publicKey", publicKeyString);
keyPairMap.put("privateKey", privateKeyString);
return keyPairMap;
}
public static String encrypt(String str, String publicKey) throws Exception {
byte[] decoded = Base64.decodeBase64(publicKey);
RSAPublicKey pubKey = (RSAPublicKey) KeyFactory.getInstance("RSA")
.generatePublic(new X509EncodedKeySpec(decoded));
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
cipher.init(1, pubKey);
// 分段加密
// URLEncoder编码解决中文乱码问题
byte[] data = URLEncoder.encode(str, "UTF-8").getBytes("UTF-8");
// 加密时超过117字节就报错。为此采用分段加密的办法来加密
byte[] enBytes = null;
for (int i = 0; i < data.length; i += MAX_ENCRYPT_BLOCK) {
// 注意要使用2的倍数否则会出现加密后的内容再解密时为乱码
byte[] doFinal = cipher.doFinal(ArrayUtils.subarray(data, i, i + MAX_ENCRYPT_BLOCK));
enBytes = ArrayUtils.addAll(enBytes, doFinal);
}
String outStr = Base64.encodeBase64String(enBytes);
return outStr;
}
/**
* 公钥分段解密
*
* @param str
* @param privateKey
* @return
* @throws Exception
*/
public static String decrypt(String str, String privateKey) throws Exception {
// 获取公钥
byte[] decoded = Base64.decodeBase64(privateKey);
RSAPrivateKey priKey = (RSAPrivateKey) KeyFactory.getInstance("RSA")
.generatePrivate(new PKCS8EncodedKeySpec(decoded));
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
cipher.init(2, priKey);
byte[] data = Base64.decodeBase64(str.getBytes("UTF-8"));
// 返回UTF-8编码的解密信息
int inputLen = data.length;
ByteArrayOutputStream out = new ByteArrayOutputStream();
int offSet = 0;
byte[] cache;
int i = 0;
// 对数据分段解密
while (inputLen - offSet > 0) {
if (inputLen - offSet > MAX_DECRYPT_BLOCK) {
cache = cipher.doFinal(data, offSet, MAX_DECRYPT_BLOCK);
} else {
cache = cipher.doFinal(data, offSet, inputLen - offSet);
}
out.write(cache, 0, cache.length);
i++;
offSet = i * 128;
}
byte[] decryptedData = out.toByteArray();
out.close();
return URLDecoder.decode(new String(decryptedData, "UTF-8"), "UTF-8");
}
2024-05-11 16:40:25 +08:00
public static void main(String[] args) throws Exception {
Map<String, String> keyMap = genKeyPair();
2024-05-24 18:54:30 +08:00
String publicKey = keyMap.get("publicKey");
String privateKey = keyMap.get("privateKey");
privateKey = "MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAK4gHFgxhaAhq7UEqNOkz/0mEgdGc7hChqI6tUmT44VYAkWkWtmgOPclhAXjLAPy5Y7HbwQF/6D5TxQgTSlL3cgS+b87jtU7BKpK9zm2leavEdNWAdKpxepeSbj6rrhznbk3luFRtF5cj8JIpTrYQfsxZqmMcPu88oZULCODxEcJAgMBAAECgYAA+yU4/xgPny6Sm97ChoD80k6pzpubAP6URKJMXSQcFBaxtPnZivfU005qNY7qGApXBj69Otw8pC8YvsP+KEsHAmPS78AmzAlh6rojkwl+A1F3a23CyxWKDik/HWsXJ1WSl5ljw/+rW6/38YVfPEKZSOWOTwfYxFWI553j05CVKQJBALkhR60uwGaGpV1ApHwcuaSN6rVQ46D67qmkKG3rLkZJyDziFBabl685UCKiDXqwRoX3UWI0FDqDUhSqoBo/LJUCQQDwyGJiUIAI8bTj6q4+1LxeHMlcJWXaRvOK0BocH+6KpybMKf0R478ziYTtNiaSY45syaDQKofVyE8kzTN37J+lAkAs9EHdcd7ShpudG1dVs/v4U2XNBYlgy84sb2pJ1rPz6XKwJg3Ot5WLvRUSc9tmEWvul/GxMQhAdSb3Ub9y4ChJAkEA7Wj3MO8kvyzr6gpcklEaBkWl+TharBVnTwiPpgmKH6ZeZ9JC2B/SR9OhgG7zK0YEiZlo+bflxVHDT4sQ438pjQJBALIQpdg34BQwWMTx4MxP0Wji51JDZM7h24SReb0RktfsY9s6ZU6mbu3oJNnInD+GQkRJkYNkK4DPrczIxnMpddE=";
publicKey = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCuIBxYMYWgIau1BKjTpM/9JhIHRnO4QoaiOrVJk+OFWAJFpFrZoDj3JYQF4ywD8uWOx28EBf+g+U8UIE0pS93IEvm/O47VOwSqSvc5tpXmrxHTVgHSqcXqXkm4+q64c525N5bhUbReXI/CSKU62EH7MWapjHD7vPKGVCwjg8RHCQIDAQAB";
2024-05-24 18:54:30 +08:00
log.info("publicKey = " + publicKey);
log.info("privateKey = " + privateKey);
String originValue = "{\n"
+ " \"data\": {\n"
+ " \"a\": 1,\n"
+ " \"b\": \"dd\"\n"
+ " },\n"
+ " \"divideHttpUrl\": {\n"
+ " \"company\": {\n"
+ " \"aesKey\": \"dadddsdfadfadsfa33323223\"\n"
+ " }\n"
+ " }\n"
+ "}";
2024-05-24 18:54:30 +08:00
// 加密前原数据123456测试一下
System.out.println("加密前:" + originValue);
String encrypt = encrypt(originValue, publicKey);
log.info("加密后:" + encrypt);
encrypt = "Rk3UOW4UG+a/MmnddEvv03mdcv5B2+Rhu7A7mRuu9MgBTBTYrX8RVRgLwXkQq5Wuo8O33/b9n6qGhLX/GDWQ4unuO0IR4wkYwbL5EOXkOmozxScfSyiypu1zD+hSw+B4uMO5LZql+jRJeCtEjph9RZK5EFD186qktUWP1QcKHzGGIM7Ex1YZogWdn6g2I3iyYTStJrofWfUtMQzEj2UUbaAJ/KuCKSXBAJ1oBjmfT856R9TZrHxVXLf5+jNgoUQrSit6ca/hZ8HSZ+rRLf9r+pgAsU0zYLmifRVDc+F819I3XIdi/FNNm9fwNuX7ZpXyKAGP93j8V35uQ6p1ZMw+xQ==";
2024-05-24 18:54:30 +08:00
String decrypt = decrypt(encrypt, privateKey);
log.info("解密后:" + decrypt);
2024-05-11 16:40:25 +08:00
}
}