参数加密
企税通目前支持DES、RSA256、SM2、SM4四种加密方式。 密钥由系统生成提供,用于接口信息加密解密,请务必注意保密。
1. Header参数说明
algorithm为可选参数,参数值为DES、RSA256、SM2、SM4四种,表示接口需要加密的加密算法。
示例:
curl --location --recognizeBankCardRequest POST 'http://127.0.0.1:8080/test' \
--header 'timestamp: 1651671975016' \
--header 'secretId: YWhkYndkamtod2prZHdk' \
--header 'signature: 33fa3a54d83021a105e23bbb0b9ebcbda8af7560ea0bcdf2089186244cdc6e1b' \
--header 'algorithm: RSA256' \
--header 'Content-Type: application/json' \
--data-raw '{"ip":"127.0.0.1"}'
2. RSA256加解密
请求信息使用公钥加密,公钥解密。
Java示例:
import com.yonyoufintech.ezdev.crypto.asymmetric.KeyType;
import com.yonyoufintech.ezdev.crypto.asymmetric.RSA;
public class XXX {
public static final String KEY_ALGORITHM = "RSA";
// 1024 bits 的 RSA 密钥对,最大加密明文大小
private static final int MAX_ENCRYPT_BLOCK = 117;
// 1024 bits 的 RSA 密钥对,最大解密密文大小
private static final int MAX_DECRYPT_BLOCK = 128;
private String publicKeyStr = "";
private String privateKeyStr = "";
/**
* rsa公钥加密
*
* @param bytes 需加密数据
* @return 加密后byte数据
*/
public byte[] encrypt(byte[] bytes) {
try {
PublicKey publicKey = getPublicKey(publicKeyStr);
Cipher cipher = Cipher.getInstance(KEY_ALGORITHM);
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
int inputLen = bytes.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(bytes, offSet, MAX_ENCRYPT_BLOCK);
} else {
cache = cipher.doFinal(bytes, offSet, inputLen - offSet);
}
out.write(cache, 0, cache.length);
i++;
offSet = i * MAX_ENCRYPT_BLOCK;
}
byte[] plainText = out.toByteArray();
out.close();
return plainText;
} catch (Exception e) {
throw new RuntimeException("公钥加密异常", e);
}
}
/**
* rsa公钥解密
*
* @param bytes 需解密数据
* @return 解密后byte数组
*/
public byte[] decrypt(byte[] bytes) {
try {
PublicKey publicKey = getPrivateKey(publicKeyStr);
Cipher cipher = Cipher.getInstance(KEY_ALGORITHM);
cipher.init(Cipher.DECRYPT_MODE, publicKey);
int inputLen = bytes.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(bytes, offSet, MAX_DECRYPT_BLOCK);
} else {
cache = cipher.doFinal(bytes, offSet, inputLen - offSet);
}
out.write(cache, 0, cache.length);
i++;
offSet = i * MAX_DECRYPT_BLOCK;
}
byte[] plainText = out.toByteArray();
out.close();
return plainText;
} catch (Exception e) {
throw new RuntimeException("公钥解密异常", e);
}
}
// 获取公钥
public static PublicKey getPublicKey(String publicKeyString) throws NoSuchAlgorithmException, InvalidKeySpecException {
if (StringUtils.isEmpty(publicKeyString)) {
throw new RuntimeException("publicKey为空");
}
byte[] publicKeyByte = Base64.getDecoder().decode(publicKeyString);
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(publicKeyByte);
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
return keyFactory.generatePublic(keySpec);
}
public static PublicKey getCertificatePublicKey(String certificateBase64) throws Exception {
String base64EncodedCerts = "-----BEGIN CERTIFICATE-----\n" + certificateBase64 + "\n-----END CERTIFICATE-----\n";
final ByteArrayInputStream streamCertificate = new ByteArrayInputStream(base64EncodedCerts.getBytes(StandardCharsets.UTF_8));
// BC 的意思,是指定用BouncyCastleProvider 。
CertificateFactory certFactory = CertificateFactory.getInstance("X.509", "BC");
X509Certificate x509Certificate = (X509Certificate) certFactory.generateCertificate(streamCertificate);
PublicKey publicKey = x509Certificate.getPublicKey();
return publicKey;
}
// 获取私钥
public static PrivateKey getPrivateKey(String privateKeyString) throws Exception {
if (StringUtils.isEmpty(privateKeyString)) {
throw new RuntimeException("privateKey为空");
}
byte[] privateKeyByte = Base64.getDecoder().decode(privateKeyString);
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(privateKeyByte);
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
return keyFactory.generatePrivate(keySpec);
}
}
3. DES加解密
请求信息使用密钥加密,解密。
Java示例:
import com.yonyoufintech.qstsdk.utils.safety.symmetric.DES;
public class XXX {
/**
DES密钥
*/
String key = "";
//默认工作模式:ECB、填充方式: PKCS7Padding
DES des = new DES();
//加密
private static byte[] encrypt(byte[] data) {
return des.encrypt(data, Base64.getDecoder().decode(key));
}
//解密
private static byte[] decrypt(byte[] data) {
return des.decrypt(data, Base64.getDecoder().decode(key));
}
}
4. SM2加解密
请求信息使用公钥加密,私钥解密。
Java示例:
import org.bouncycastle.asn1.gm.GMNamedCurves;
import org.bouncycastle.asn1.x9.X9ECParameters;
import org.bouncycastle.jcajce.spec.OpenSSHPrivateKeySpec;
import org.bouncycastle.jcajce.spec.OpenSSHPublicKeySpec;
import org.bouncycastle.jce.spec.ECParameterSpec;
import org.bouncycastle.jce.spec.ECPrivateKeySpec;
import org.bouncycastle.jce.spec.ECPublicKeySpec;
import org.bouncycastle.math.ec.ECPoint;
public class XXX {
//私钥
String privateKeyStr = "";
//公钥
String publicKeyStr = "";
/**
* 获取SM2相关参数
*/
private static X9ECParameters X9_EC_PARAMETERS;
/**
* 椭圆曲线参数规格
*/
private static ECParameterSpec EC_PARAMETER_SPEC;
private static final String KEY_ALGORITHM = "EC";
private static final String SM2_ALGORITHM = "SM2";
private static PrivateKey privateKey;
private static PublicKey publicKey;
static {
X9_EC_PARAMETERS = GMNamedCurves.getByName("sm2p256v1");
EC_PARAMETER_SPEC = new ECParameterSpec(X9_EC_PARAMETERS.getCurve(), X9_EC_PARAMETERS.getG(),
X9_EC_PARAMETERS.getN(), X9_EC_PARAMETERS.getH());
try {
privateKey = getPrivateKey(privateKeyStr);
publicKey = getPublicKey(publicKeyStr);
} catch (Exception e) {
throw new RuntimeException("私钥初始化异常", e);
}
}
/**
* sm2公钥加密
*
* @param bytes 需加密数据
* @return 加密后byte数据
*/
public byte[] encrypt(byte[] bytes) {
try {
Cipher cipher = Cipher.getInstance(SM2_ALGORITHM, GlobalBouncyCastleProvider.INSTANCE.getProvider());
cipher.init(Cipher.ENCRYPT_MODE, PUBLIC_KEY);
return cipher.doFinal(bytes);
} catch (Exception e) {
throw new RuntimeException("公钥加密异常", e);
}
}
/**
* sm2私钥解密
*
* @param bytes 需解密数据
* @return 解密后byte数组
*/
public byte[] decrypt(byte[] bytes) {
try {
Cipher cipher = Cipher.getInstance(SM2_ALGORITHM, GlobalBouncyCastleProvider.INSTANCE.getProvider());
cipher.init(Cipher.DECRYPT_MODE, PRIVATE_KEY);
return cipher.doFinal(bytes);
} catch (Exception e) {
throw new RuntimeException("私钥解密异常", e);
}
}
public static PublicKey getCertificatePublicKey(String certificateBase64) throws Exception {
String base64EncodedCerts = "-----BEGIN CERTIFICATE-----\n" + certificateBase64 + "\n-----END CERTIFICATE-----\n";
final ByteArrayInputStream streamCertificate = new ByteArrayInputStream(base64EncodedCerts.getBytes(StandardCharsets.UTF_8));
// BC 的意思,是指定用BouncyCastleProvider 。
CertificateFactory certFactory = CertificateFactory.getInstance("X.509", "BC");
X509Certificate x509Certificate = (X509Certificate) certFactory.generateCertificate(streamCertificate);
PublicKey publicKey = x509Certificate.getPublicKey();
return publicKey;
}
// 获取公钥
public static PublicKey getPublicKey(String publicKeyString) throws Exception {
if (StringUtils.isEmpty(publicKeyString)) {
throw new RuntimeException("publicKey未配置");
}
byte[] encodedKey = Base64.decodeBase64(publicKeyString);
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM, GlobalBouncyCastleProvider.INSTANCE.getProvider());
try {
ECPoint ecPoint = X9_EC_PARAMETERS.getCurve().decodePoint(encodedKey);
return keyFactory.generatePublic(new ECPublicKeySpec(ecPoint, EC_PARAMETER_SPEC));
} catch (Exception e) {
//ignore
}
PublicKey pubKey;
try {
X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(encodedKey);
pubKey = keyFactory.generatePublic(x509EncodedKeySpec);
} catch (InvalidKeySpecException e) {
OpenSSHPublicKeySpec openSSHPublicKeySpec = new OpenSSHPublicKeySpec(encodedKey);
try {
pubKey = keyFactory.generatePublic(openSSHPublicKeySpec);
} catch (InvalidKeySpecException ex) {
throw new CryptoException(ex);
}
}
return pubKey;
}
// 获取私钥
public static PrivateKey getPrivateKey(String privateKeyString) throws Exception {
if (StringUtils.isEmpty(privateKeyString)) {
throw new RuntimeException("privateKey未配置");
}
byte[] encodedKey = Base64.decodeBase64(privateKeyString);
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM, GlobalBouncyCastleProvider.INSTANCE.getProvider());
try {
BigInteger bigInteger = new BigInteger(new String(encodedKey), 16);
return keyFactory.generatePrivate(new ECPrivateKeySpec(bigInteger,
EC_PARAMETER_SPEC));
} catch (Exception e) {
// ignore
}
PrivateKey priKey;
try {
PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(encodedKey);
priKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec);
} catch (InvalidKeySpecException e) {
OpenSSHPrivateKeySpec openSSHPrivateKeySpec = new OpenSSHPrivateKeySpec(encodedKey);
try {
priKey = keyFactory.generatePrivate(openSSHPrivateKeySpec);
} catch (InvalidKeySpecException ex) {
throw new CryptoException(ex);
}
}
return priKey;
}
}
5. SM4加解密
请求信息使用密钥加密,解密。
Java示例:
import com.yonyoufintech.qstsdk.utils.safety.symmetric.SM4;
public class XXX {
/**
SM4密钥
*/
String key = "";
//默认工作模式:ECB、填充方式: PKCS7Padding
SM4 sm4 = new SM4();
//加密
private static byte[] encrypt( byte[] data) {
return sm4.encrypt(data, Base64.getDecoder().decode(key));
}
//解密
private static byte[] decrypt(Rbyte[] data) {
return sm4.decrypt(data, Base64.getDecoder().decode(key));
}
}