import example.common.constants.CommonConstants;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.lang3.StringUtils;
import javax.crypto.Cipher;
import java.io.ByteArrayOutputStream;
import java.security.*;
import java.security.interfaces.RSAPrivateCrtKey;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
public class RsaCryptUtils {
public static final String SIGNATURE_INSTANCE = "SHA256WithRSA";
/**
* 数字签名,密钥算法
*/
private static final String RSA_KEY_ALGORITHM = "RSA";
/**
* 生成密钥对
*/
private static Map<String, String> initKey() {
KeyPairGenerator kpg = null;
try {
kpg = KeyPairGenerator.getInstance(RSA_KEY_ALGORITHM);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
kpg.initialize(1024);
KeyPair kp = kpg.generateKeyPair();
RSAPublicKey publicKey = (RSAPublicKey) kp.getPublic();
RSAPrivateCrtKey privateKey = (RSAPrivateCrtKey) kp.getPrivate();
String publicKeyString = Base64.encodeBase64String(publicKey.getEncoded());
String privateKeyString = Base64.encodeBase64String(privateKey.getEncoded());
Map<String, String> keyPairMap = new HashMap<>();
keyPairMap.put("publicKeyString", publicKeyString);
keyPairMap.put("privateKeyString", privateKeyString);
return keyPairMap;
}
/**
* 密钥转成字符串
*
* @param key
* @return
*/
public static String encodeBase64String(byte[] key) {
return Base64.encodeBase64String(key);
}
/**
* 密钥转成byte[]
*
* @param key
* @return
*/
public static byte[] decodeBase64(String key) {
return Base64.decodeBase64(key);
}
/**
* 公钥加密
*
* @param data 加密前的字符串
* @param publicKey 公钥
* @return 加密后的字符串
* @throws Exception
*/
public static String encryptByPubKey(String data, String publicKey) throws Exception {
byte[] pubKey = RsaCryptUtils.decodeBase64(publicKey);
byte[] enSign = encryptByPubKey(data.getBytes(), pubKey);
return Base64.encodeBase64String(enSign);
}
/**
* 公钥加密
*
* @param data 待加密数据
* @param pubKey 公钥
* @return
* @throws Exception
*/
public static byte[] encryptByPubKey(byte[] data, byte[] pubKey) throws Exception {
X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(pubKey);
KeyFactory keyFactory = KeyFactory.getInstance(RSA_KEY_ALGORITHM);
PublicKey publicKey = keyFactory.generatePublic(x509KeySpec);
Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
return cipher.doFinal(data);
}
/**
* 私钥加密
*
* @param data 加密前的字符串
* @param privateKey 私钥
* @return 加密后的字符串
* @throws Exception
*/
public static String encryptByPriKey(String data, String privateKey) throws Exception {
byte[] priKey = RsaCryptUtils.decodeBase64(privateKey);
byte[] enSign = encryptByPriKey(data.getBytes(), priKey);
return Base64.encodeBase64String(enSign);
}
/**
* 私钥加密
*
* @param data 待加密的数据
* @param priKey 私钥
* @return 加密后的数据
* @throws Exception
*/
public static byte[] encryptByPriKey(byte[] data, byte[] priKey) throws Exception {
PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(priKey);
KeyFactory keyFactory = KeyFactory.getInstance(RSA_KEY_ALGORITHM);
PrivateKey privateKey = keyFactory.generatePrivate(pkcs8KeySpec);
Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
cipher.init(Cipher.ENCRYPT_MODE, privateKey);
return cipher.doFinal(data);
}
/**
* 公钥解密
*
* @param data 待解密的数据
* @param pubKey 公钥
* @return 解密后的数据
* @throws Exception
*/
public static byte[] decryptByPubKey(byte[] data, byte[] pubKey) throws Exception {
X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(pubKey);
KeyFactory keyFactory = KeyFactory.getInstance(RSA_KEY_ALGORITHM);
PublicKey publicKey = keyFactory.generatePublic(x509KeySpec);
Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
cipher.init(Cipher.DECRYPT_MODE, publicKey);
return cipher.doFinal(data);
}
/**
* 公钥解密
*
* @param data 解密前的字符串
* @param publicKey 公钥
* @return 解密后的字符串
* @throws Exception
*/
public static String decryptByPubKey(String data, String publicKey) throws Exception {
byte[] pubKey = RsaCryptUtils.decodeBase64(publicKey);
byte[] design = decryptByPubKey(Base64.decodeBase64(data), pubKey);
return new String(design);
}
/**
* 私钥解密
*
* @param data 待解密的数据
* @param priKey 私钥
* @return
* @throws Exception
*/
public static byte[] decryptByPriKey(byte[] data, byte[] priKey) throws Exception {
PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(priKey);
KeyFactory keyFactory = KeyFactory.getInstance(RSA_KEY_ALGORITHM);
PrivateKey privateKey = keyFactory.generatePrivate(pkcs8KeySpec);
Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
cipher.init(Cipher.DECRYPT_MODE, privateKey);
return cipher.doFinal(data);
}
/**
* 私钥解密
*
* @param data 解密前的字符串
* @param privateKey 私钥
* @return 解密后的字符串
* @throws Exception
*/
public static String decryptByPriKey(String data, String privateKey) throws Exception {
byte[] priKey = RsaCryptUtils.decodeBase64(privateKey);
byte[] design = decryptByPriKey(Base64.decodeBase64(data), priKey);
return new String(design);
}
// public static void main(String[] args) {
// try {
Map<String, String> keyMap = initKey();
String publicKeyString = keyMap.get(“publicKeyString”);
String privateKeyString = keyMap.get(“privateKeyString”);
System.out.println(“公钥:” + publicKeyString);
System.out.println(“私钥:” + privateKeyString);
//
//公钥:216
//私钥:848
// 待加密数据
// Map<String, Object> jsonObject = new HashMap<>();
jsonObject.put(“api_key”, “AQUAA4GNADCBiQKBgQCeOGG7ck”);
jsonObject.put(“time”, System.currentTimeMillis());
jsonObject.put(“id”, “sino”);
// String data = getMapToString(jsonObject);
// System.out.println(data);
// 公钥加密
String encrypt = RsaCryptUtils.encryptByPubKey(data, publicKeyString);
// 私钥解密
String decrypt = RsaCryptUtils.decryptByPriKey(encrypt, privateKeyString);
System.out.println(“加密前:” + data);
System.out.println(“加密后:” + encrypt);
System.out.println(“解密后:” + decrypt);
System.out.println(“解密后:” + getStringToMap(decrypt));
System.out.println(“URLEncoder:” + URLEncoder.encode(encrypt, “UTf-8”));
System.out.println(“URLDecoder:” + URLDecoder.decode(encrypt, “UTf-8”));
// } catch (Exception e) {
// e.printStackTrace();
// }
// }
/**
* RSA公钥加密
*
* @param str 加密字符串
* @param publicKey 公钥
* @return 密文
* @throws Exception 加密过程中的异常信息
*/
public static String blockEncryptByPubKey(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");
cipher.init(Cipher.ENCRYPT_MODE, pubKey);
byte[] bytes = str.getBytes();
int inputLen = bytes.length;
int offLen = 0;//偏移量
int i = 0;
ByteArrayOutputStream bops = new ByteArrayOutputStream();
while (inputLen - offLen > 0) {
byte[] cache;
if (inputLen - offLen > 117) {
cache = cipher.doFinal(bytes, offLen, 117);
} else {
cache = cipher.doFinal(bytes, offLen, inputLen - offLen);
}
bops.write(cache);
i++;
offLen = 117 * i;
}
bops.close();
byte[] encryptedData = bops.toByteArray();
String encodeToString = Base64.encodeBase64String(encryptedData);
return encodeToString;
}
/**
* RSA私钥解密
*
* @param str 加密字符串
* @param privateKey 私钥
* @return 铭文
* @throws Exception 解密过程中的异常信息
*/
public static String blockDecryptByPriKey(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");
cipher.init(Cipher.DECRYPT_MODE, priKey);
byte[] bytes = Base64.decodeBase64(str);
int inputLen = bytes.length;
int offLen = 0;
int i = 0;
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
while (inputLen - offLen > 0) {
byte[] cache;
if (inputLen - offLen > 128) {
cache = cipher.doFinal(bytes, offLen, 128);
} else {
cache = cipher.doFinal(bytes, offLen, inputLen - offLen);
}
byteArrayOutputStream.write(cache);
i++;
offLen = 128 * i;
}
byteArrayOutputStream.close();
byte[] byteArray = byteArrayOutputStream.toByteArray();
return new String(byteArray);
}
/**
* map转str
*
* @param map
* @return
*/
public static String getMapToString(Map<String, Object> map) {
Set<String> keySet = map.keySet();
//将set集合转换为数组
String[] keyArray = keySet.toArray(new String[keySet.size()]);
//给数组排序(升序)
Arrays.sort(keyArray);
//因为String拼接效率会很低的,所以转用StringBuilder。博主会在这篇博文发后不久,会更新一篇String与StringBuilder开发时的抉择的博文。
StringBuilder sb = new StringBuilder();
for (int i = 0; i < keyArray.length; i++) {
// 参数值为空,则不参与签名 这个方法trim()是去空格
if (map.get(keyArray[i]) != null) {
sb.append(keyArray[i]).append(CommonConstants.SPLIT_EQUAL).append(map.get(keyArray[i]).toString());
} else {
sb.append(keyArray[i]).append(CommonConstants.SPLIT_EQUAL).append(CommonConstants.EMPTY);
}
if (i != keyArray.length - 1) {
sb.append(CommonConstants.SPLIT_AND);
}
}
return sb.toString();
}
/**
* String转map
*
* @param str
* @return
*/
public static Map<String, Object> getStringToMap(String str) {
//感谢bojueyou指出的问题
//判断str是否有值
if (StringUtils.isEmpty(str)) {
return null;
}
//根据&截取
String[] strings = str.split(CommonConstants.SPLIT_AND);
//设置HashMap长度
int mapLength = strings.length;
//判断hashMap的长度是否是2的幂。
if ((strings.length % 2) != 0) {
mapLength = mapLength + 1;
}
Map<String, Object> map = new HashMap<>(mapLength);
//循环加入map集合
for (int i = 0; i < strings.length; i++) {
//截取一组字符串
String[] strArray = strings[i].split(CommonConstants.SPLIT_EQUAL);
//strArray[0]为KEY strArray[1]为值
map.put(strArray[0], strArray[1]);
}
return map;
}
}