加解密
概述
如果对接者在接入前准备的第三方系统配置中,配置了AES+BASE64的加密策略,则需要对请求报文做加密,对返回结果做解密,本文给出加解密示例。
:::tip
目前加密策略仅对开票所有能力和收票的勾选接口起作用
:::
报文加密
加密前报文:
{
"requestId": "1624601109096",
"businessSystemCode": "BAIDU_TEST",
"interfaceCode": "INVOICE.QUERY",
"data": {
"serialNo": "34234FPY123456refe4",
"sellerTaxpayerId": "915003006188392540",
"invoiceDateS": "2021-06-24 00:00:00",
"invoiceDateE": "2021-06-26 00:00:00",
"invoiceStatus": "",
"invoiceType": "",
"pageNo": 1,
"pageSize": 50
}
}
加密后报文:
{
"requestId": "1624601109096",
"businessSystemCode": "BAIDU_TEST",
"interfaceCode": "INVOICE.QUERY",
"data": "sdfsdf2332rfsdfSDF23RDS&@SDFSDFSDCX212423SDFSG4353454323423423DVDFDFG23RSDFSDCSDCV"
}
示例代码:
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.GCMParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.util.Base64;
public class AESUtil {
private static final String KEY_ALGORITHM_AES = "AES";
private static final String DEFAULT_CIPHER_ALGORITHM = "AES/GCM/NoPadding";
private static final String CHARSET = "UTF-8";
/**
* 加密
* @param content 原文
* @param encryptPass AES加密KEY
* @return
*/
public static String aesEncrypt(String content, String encryptPass) {
try {
byte[] iv = new byte[12];
SecureRandom secureRandom = new SecureRandom();
secureRandom.nextBytes(iv);
byte[] contentBytes = content.getBytes(CHARSET);
Cipher cipher = Cipher.getInstance(DEFAULT_CIPHER_ALGORITHM);
GCMParameterSpec params = new GCMParameterSpec(128, iv);
cipher.init(Cipher.ENCRYPT_MODE, getSecretKey(encryptPass), params);
byte[] encryptData = cipher.doFinal(contentBytes);
assert encryptData.length == contentBytes.length + 16;
byte[] message = new byte[12 + contentBytes.length + 16];
System.arraycopy(iv, 0, message, 0, 12);
System.arraycopy(encryptData, 0, message, 12, encryptData.length);
return Base64.getEncoder().encodeToString(message);
} catch (Exception e) {
}
return null;
}
/**
* 解密
* @param base64Content 密文
* @param encryptPass AES加密KEY
* @return
*/
public static String aesDecrypt(String base64Content, String encryptPass) {
try {
byte[] content = Base64.getDecoder().decode(base64Content);
if (content.length < 12 + 16) {
throw new IllegalArgumentException();
}
GCMParameterSpec params = new GCMParameterSpec(128, content, 0, 12);
Cipher cipher = Cipher.getInstance(DEFAULT_CIPHER_ALGORITHM);
cipher.init(Cipher.DECRYPT_MODE, getSecretKey(encryptPass), params);
byte[] decryptData = cipher.doFinal(content, 12, content.length - 12);
return new String(decryptData, CHARSET);
} catch (Exception e) {
}
return null;
}
/**
* 秘钥
* @return
* @throws NoSuchAlgorithmException
*/
private static SecretKeySpec getSecretKey(String encryptPass) throws NoSuchAlgorithmException {
KeyGenerator kg = KeyGenerator.getInstance(KEY_ALGORITHM_AES);
SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG");
secureRandom.setSeed(encryptPass.getBytes());
kg.init(128, secureRandom);
SecretKey secretKey = kg.generateKey();
return new SecretKeySpec(secretKey.getEncoded(), KEY_ALGORITHM_AES);
}
public static void main(String[] args) {
String s = AESUtil.aesEncrypt("123456", "R5c58SI9toLpxBkv");
System.out.println("加密密文:" + s);
String p = AESUtil.aesDecrypt(s, "R5c58SI9toLpxBkv");
System.out.println("解密:" + p);
}
}
报文解密
对于业务接口data返回的数据,先进行base64解密,然后使用aesKey进行AES解密 (或直接调用示例代码里的AESUtil.aesDecrypt 方法)
Last modified: 10 个月前