137 lines
4.5 KiB
Java
137 lines
4.5 KiB
Java
package com.yutou.qqbot.utlis;
|
||
|
||
import org.apache.commons.codec.binary.Base64;
|
||
|
||
import javax.crypto.Cipher;
|
||
import java.io.ByteArrayOutputStream;
|
||
import java.security.*;
|
||
import java.security.spec.PKCS8EncodedKeySpec;
|
||
import java.security.spec.X509EncodedKeySpec;
|
||
import java.util.HashMap;
|
||
import java.util.Map;
|
||
|
||
public class RSAUtils {
|
||
/**
|
||
* 加密算法RSA
|
||
*/
|
||
public static final String KEY_ALGORITHM = "RSA";
|
||
|
||
/**
|
||
* 签名算法
|
||
*/
|
||
public static final String SIGNATURE_ALGORITHM = "MD5withRSA";
|
||
|
||
/**
|
||
* 获取公钥的key
|
||
*/
|
||
private static final String PUBLIC_KEY = "RSAPublicKey";
|
||
|
||
/**
|
||
* 获取私钥的key
|
||
*/
|
||
private static final String PRIVATE_KEY = "RSAPrivateKey";
|
||
|
||
/**
|
||
* RSA 密钥位数
|
||
*/
|
||
private static final int KEY_SIZE = 1024;
|
||
|
||
/**
|
||
* RSA最大解密密文大小
|
||
*/
|
||
private static final int MAX_DECRYPT_BLOCK = KEY_SIZE / 8;
|
||
|
||
/**
|
||
* RSA最大加密明文大小
|
||
*/
|
||
private static final int MAX_ENCRYPT_BLOCK = MAX_DECRYPT_BLOCK - 11;
|
||
private static Map<Integer,String> keyMap=new HashMap<>();
|
||
|
||
/**
|
||
* 随机生成密钥对
|
||
* @throws NoSuchAlgorithmException
|
||
*/
|
||
public static void getKeyPair() throws Exception {
|
||
//KeyPairGenerator类用于生成公钥和密钥对,基于RSA算法生成对象
|
||
KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA");
|
||
//初始化密钥对生成器,密钥大小为96-1024位
|
||
keyPairGen.initialize(1024,new SecureRandom());
|
||
//生成一个密钥对,保存在keyPair中
|
||
KeyPair keyPair = keyPairGen.generateKeyPair();
|
||
PrivateKey privateKey = keyPair.getPrivate();//得到私钥
|
||
PublicKey publicKey = keyPair.getPublic();//得到公钥
|
||
//得到公钥字符串
|
||
String publicKeyString=new String(Base64.encodeBase64(publicKey.getEncoded()));
|
||
//得到私钥字符串
|
||
String privateKeyString=new String(Base64.encodeBase64(privateKey.getEncoded()));
|
||
//将公钥和私钥保存到Map
|
||
keyMap.put(0,publicKeyString);//0表示公钥
|
||
keyMap.put(1,privateKeyString);//1表示私钥
|
||
}
|
||
/**
|
||
* <p>
|
||
* 公钥加密
|
||
* </p>
|
||
*
|
||
* @param str 源数据
|
||
* @param publicKey 公钥(BASE64编码)
|
||
* @return
|
||
* @throws Exception
|
||
*/
|
||
public static String encryptByPublicKey(String str, String publicKey) throws Exception {
|
||
publicKey=publicKey.replace("-----BEGIN PUBLIC KEY-----","").replace("-----END PUBLIC KEY-----","");
|
||
byte[] data=Base64.decodeBase64(str);
|
||
byte[] keyBytes = Base64.decodeBase64(publicKey);
|
||
X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);
|
||
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
|
||
Key publicK = keyFactory.generatePublic(x509KeySpec);
|
||
// 对数据加密
|
||
Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
|
||
cipher.init(Cipher.ENCRYPT_MODE, publicK);
|
||
int inputLen = data.length;
|
||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||
int offSet = 0;
|
||
byte[] cache;
|
||
int i = 0;
|
||
// 对数据分段加密
|
||
while (inputLen - offSet > 0) {
|
||
if (inputLen - offSet > MAX_ENCRYPT_BLOCK) {
|
||
cache = cipher.doFinal(data, offSet, MAX_ENCRYPT_BLOCK);
|
||
} else {
|
||
cache = cipher.doFinal(data, offSet, inputLen - offSet);
|
||
}
|
||
out.write(cache, 0, cache.length);
|
||
i++;
|
||
offSet = i * MAX_ENCRYPT_BLOCK;
|
||
}
|
||
byte[] encryptedData = out.toByteArray();
|
||
out.close();
|
||
return new String(Base64.encodeBase64(encryptedData));
|
||
}
|
||
|
||
/**
|
||
* RSA私钥解密
|
||
*
|
||
* @param str
|
||
* 加密字符串
|
||
* @param privateKey
|
||
* 私钥
|
||
* @return 铭文
|
||
* @throws Exception
|
||
* 解密过程中的异常信息
|
||
*/
|
||
public static String decrypt(String str,String privateKey) throws Exception {
|
||
//Base64解码加密后的字符串
|
||
byte[] inputByte = Base64.decodeBase64(str.getBytes("UTF-8"));
|
||
//Base64编码的私钥
|
||
byte[] decoded = Base64.decodeBase64(privateKey);
|
||
PrivateKey priKey = KeyFactory.getInstance("RSA").generatePrivate(new PKCS8EncodedKeySpec(decoded));
|
||
//RSA解密
|
||
Cipher cipher = Cipher.getInstance("RSA");
|
||
cipher.init(Cipher.DECRYPT_MODE,priKey);
|
||
String outStr=new String(cipher.doFinal(inputByte));
|
||
return outStr;
|
||
|
||
}
|
||
}
|