SRA 加密数据传输 实战
(1)list集合作为入参
public void getReferee(List<Shop> list) {
if (Objects.nonNull(list)) {
log.info("入参:"+jiagong(list));
String result = transmitPost(withdrawal,jiagong(list));
log.info("返回信息 : "+result);
}
}
(2)实体类作为入参
public JSONObject getPool(BonusRequest b) {
log.info(“入参:”+jiagong(b));
String result = transmitPost(url,jiagong(b));
log.info("返回信息 : "+result);
return JSONObject.parseObject(result);
}
(3)封装发送公共方法
private String transmitPost(String url,String data){
try {
RSAPublicKey puk = RSAUtils.getPublicKey(publickey);
String encrypt = RSAUtils.encryptByPublicKey(data,puk);
JSONObject jsonObject = new JSONObject();
jsonObject.put("data",encrypt);
log.info("加密后:"+jsonObject.toJSONString());
return HttpUtil.post(url, jsonObject.toJSONString());
}catch (Exception e){
log.info(e.toString());
}
return null;
}
(4)封装转义方法
public String jiagong(Object obj){
return JSONObject.toJSONString(obj);
}
(5)RSA工具类
public class RSAUtils {
public static final String CHARSET = "UTF-8";
// 加密算法
private final static String ALGORITHM_RSA = "RSA";
//公钥
public static final String PUBLIC_KEY = "publicKey";
//私钥
public static final String PRIVATE_KEY = "privateKey";
/**
* @param modulus
* @throws NoSuchAlgorithmException
* @Description: 直接生成公钥、私钥对象
*/
public static List<Key> getRSAKeyObject(int modulus) throws NoSuchAlgorithmException {
List<Key> keyList = new ArrayList<>(2);
// 创建RSA密钥生成器
KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance(ALGORITHM_RSA);
// 设置密钥的大小,此处是RSA算法的模长 = 最大加密数据的大小
keyPairGen.initialize(modulus);
KeyPair keyPair = keyPairGen.generateKeyPair();
// keyPair.getPublic() 生成的是RSAPublic的是咧
keyList.add(keyPair.getPublic());
// keyPair.getPrivate() 生成的是RSAPrivateKey的实例
keyList.add(keyPair.getPrivate());
return keyList;
}
/**
* @param modulus 模长
* @return
* @throws NoSuchAlgorithmException
* @Description: 生成公钥、私钥的字符串
*/
public static Map<String, String> getRSAKeyString(int modulus) throws NoSuchAlgorithmException {
// map装载公钥和私钥
Map<String, String> keyPairMap = new HashMap<>(16);
KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance(ALGORITHM_RSA);
keyPairGen.initialize(modulus);
KeyPair keyPair = keyPairGen.generateKeyPair();
String publicKey = Base64.getEncoder().encodeToString(keyPair.getPublic().getEncoded());
String privateKey = Base64.getEncoder().encodeToString(keyPair.getPrivate().getEncoded());
keyPairMap.put(PUBLIC_KEY, publicKey);
keyPairMap.put(PRIVATE_KEY, privateKey);
return keyPairMap;
}
/**
* @throws Exception
* @Description: Java中RSAPublicKeySpec、X509EncodedKeySpec支持生成RSA公钥
* 此处使用X509EncodedKeySpec生成
* @Param: privateKey
* @Author: 01传说
*/
public static RSAPublicKey getPublicKey(String publicKey) throws Exception {
KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM_RSA);
byte[] keyBytes = Base64.getDecoder().decode(publicKey);
X509EncodedKeySpec spec = new X509EncodedKeySpec(keyBytes);
return (RSAPublicKey) keyFactory.generatePublic(spec);
}
/**
* @throws Exception
* @Description: Java中只有RSAPrivateKeySpec、PKCS8EncodedKeySpec支持生成RSA私钥
* 此处使用PKCS8EncodedKeySpec生成
* @Param: privateKey
* @Author: 01传说
*/
public static RSAPrivateKey getPrivateKey(String privateKey) throws Exception {
KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM_RSA);
byte[] keyBytes = Base64.getDecoder().decode(privateKey);
PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(keyBytes);
return (RSAPrivateKey) keyFactory.generatePrivate(spec);
}
/**
* @param data
* @param publicKey
* @throws Exception
* @Description: 公钥加密
*/
public static String encryptByPublicKey(String data, RSAPublicKey publicKey)
throws Exception {
Cipher cipher = Cipher.getInstance(ALGORITHM_RSA);
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
// 模长n转换成字节数
int modulusSize = publicKey.getModulus().bitLength() / 8;
// PKCS Padding长度为11字节,所以实际要加密的数据不能要 - 11byte
int maxSingleSize = modulusSize - 11;
// 切分字节数组,每段不大于maxSingleSize
byte[][] dataArray = splitArray(data.getBytes(CHARSET), maxSingleSize);
ByteArrayOutputStream out = new ByteArrayOutputStream();
// 分组加密,并将加密后的内容写入输出字节流
for (byte[] s : dataArray) {
out.write(cipher.doFinal(s));
}
// 使用Base64将字节数组转换String类型
return Base64.getEncoder().encodeToString(out.toByteArray());
}
/**
* @param data
* @param privateKey
* @throws Exception
* @Description: 私钥解密
*/
public static String decryptByPrivateKey(String data, RSAPrivateKey privateKey)
throws Exception {
if( StringUtils.isEmpty(data) ) {
return null;
}
Cipher cipher = Cipher.getInstance(ALGORITHM_RSA);
cipher.init(Cipher.DECRYPT_MODE, privateKey);
// RSA加密算法的模长 n
int modulusSize = privateKey.getModulus().bitLength() / 8;
byte[] dataBytes = data.getBytes(CHARSET);
// 之前加密的时候做了转码,此处需要使用Base64进行解码
byte[] decodeData = Base64.getDecoder().decode(dataBytes);
// 切分字节数组,每段不大于modulusSize
byte[][] splitArrays = splitArray(decodeData, modulusSize);
ByteArrayOutputStream out = new ByteArrayOutputStream();
for (byte[] arr : splitArrays) {
out.write(cipher.doFinal(arr));
}
return new String(out.toByteArray());
}
/**
* @param data
* @param privateKey
* @throws Exception
* @Description: 私钥钥加密
*/
public static String encryptByPrivateKey(String data, RSAPrivateKey privateKey)
throws Exception {
Cipher cipher = Cipher.getInstance(ALGORITHM_RSA);
cipher.init(Cipher.ENCRYPT_MODE, privateKey);
// 模长n转换成字节数
int modulusSize = privateKey.getModulus().bitLength() / 8;
// PKCS Padding长度为11字节,所以实际要加密的数据不能要 - 11byte
int maxSingleSize = modulusSize - 11;
// 切分字节数组,每段不大于maxSingleSize
byte[][] dataArray = splitArray(data.getBytes(CHARSET), maxSingleSize);
ByteArrayOutputStream out = new ByteArrayOutputStream();
// 分组加密,并将加密后的内容写入输出字节流
for (byte[] s : dataArray) {
out.write(cipher.doFinal(s));
}
// 使用Base64将字节数组转换String类型
return Base64.getEncoder().encodeToString(out.toByteArray());
}
/**
* @param data
* @param publicKey
* @throws Exception
* @Description: 公钥解密
*/
public static String decryptByPublicKey(String data, RSAPublicKey publicKey)
throws Exception {
Cipher cipher = Cipher.getInstance(ALGORITHM_RSA);
cipher.init(Cipher.DECRYPT_MODE, publicKey);
// RSA加密算法的模长 n
int modulusSize = publicKey.getModulus().bitLength() / 8;
byte[] dataBytes = data.getBytes(CHARSET);
// 之前加密的时候做了转码,此处需要使用Base64进行解码
byte[] decodeData = Base64.getDecoder().decode(dataBytes);
// 切分字节数组,每段不大于modulusSize
byte[][] splitArrays = splitArray(decodeData, modulusSize);
ByteArrayOutputStream out = new ByteArrayOutputStream();
for (byte[] arr : splitArrays) {
out.write(cipher.doFinal(arr));
}
return new String(out.toByteArray());
}
/**
* @param data
* @param len 单个字节数组长度
* @Description: 按指定长度切分数组
*/
private static byte[][] splitArray(byte[] data, int len) {
int dataLen = data.length;
if (dataLen <= len) {
return new byte[][]{data};
}
byte[][] result = new byte[(dataLen - 1) / len + 1][];
int resultLen = result.length;
for (int i = 0; i < resultLen; i++) {
if (i == resultLen - 1) {
int slen = dataLen - len * i;
byte[] single = new byte[slen];
System.arraycopy(data, len * i, single, 0, slen);
result[i] = single;
break;
}
byte[] single = new byte[len];
System.arraycopy(data, len * i, single, 0, len);
result[i] = single;
}
return result;
}
}