sdf api
This commit is contained in:
@@ -15,6 +15,7 @@ import java.util.Objects;
|
||||
public enum Padding {
|
||||
NOPadding("NoPadding", "NoPadding"),
|
||||
PCKS5Padding( "PKCS5Padding", "PKCS5Padding"),
|
||||
PCKS7Padding( "PKCS7Padding", "PKCS7Padding"),
|
||||
;
|
||||
|
||||
private final String code;
|
||||
|
||||
@@ -5,6 +5,7 @@ import com.sunyard.chsm.enums.AlgMode;
|
||||
import com.sunyard.chsm.enums.KeyAlg;
|
||||
import com.sunyard.chsm.enums.KeyCategory;
|
||||
import com.sunyard.chsm.enums.Padding;
|
||||
import com.sunyard.chsm.sdf.context.AlgId;
|
||||
import com.sunyard.chsm.sdf.model.EccKey;
|
||||
import com.sunyard.chsm.sdf.util.LangUtils;
|
||||
import com.sunyard.chsm.utils.gm.BCSM2Utils;
|
||||
@@ -21,7 +22,11 @@ import javax.crypto.BadPaddingException;
|
||||
import javax.crypto.Cipher;
|
||||
import javax.crypto.IllegalBlockSizeException;
|
||||
import javax.crypto.NoSuchPaddingException;
|
||||
import java.security.*;
|
||||
import java.security.InvalidKeyException;
|
||||
import java.security.KeyPair;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.NoSuchProviderException;
|
||||
import java.security.SecureRandom;
|
||||
|
||||
|
||||
/**
|
||||
@@ -86,12 +91,22 @@ public class BCSdfApiService extends AbstractSdfApiService {
|
||||
return symCalc(Cipher.ENCRYPT_MODE, alg, mode, padding, key, data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] symEncrypt(AlgId alg, byte[] key, byte[] iv, byte[] data) {
|
||||
return new byte[0];
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public byte[] symDecrypt(KeyAlg alg, AlgMode mode, Padding padding, byte[] key, byte[] data) {
|
||||
return symCalc(Cipher.DECRYPT_MODE, alg, mode, padding, key, data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] symDecrypt(AlgId alg, byte[] key, byte[] iv, byte[] data) {
|
||||
return new byte[0];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 对称加解密的统一实现
|
||||
|
||||
@@ -4,6 +4,7 @@ package com.sunyard.chsm.sdf;
|
||||
import com.sunyard.chsm.enums.AlgMode;
|
||||
import com.sunyard.chsm.enums.KeyAlg;
|
||||
import com.sunyard.chsm.enums.Padding;
|
||||
import com.sunyard.chsm.sdf.context.AlgId;
|
||||
import com.sunyard.chsm.sdf.model.EccKey;
|
||||
|
||||
|
||||
@@ -23,41 +24,48 @@ public interface SdfApiService {
|
||||
byte[] generateRandom(int len);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 生成对称密钥
|
||||
* @param alg 算法,只支持对称算法
|
||||
*
|
||||
* @param alg 算法,只支持对称算法
|
||||
* @param keyLen 密钥长度(bit),只针对密钥长度可变的算法。
|
||||
* 禁止传 null
|
||||
* @return 对称密钥
|
||||
*/
|
||||
byte[] genSymKey(KeyAlg alg, Integer keyLen);
|
||||
|
||||
byte[] genSymKey(KeyAlg alg);
|
||||
|
||||
|
||||
/**
|
||||
* 对称加密
|
||||
* @param alg 算法,只支持对称算法
|
||||
* @param mode 轮模式
|
||||
*
|
||||
* @param alg 算法,只支持对称算法
|
||||
* @param mode 轮模式
|
||||
* @param padding 填充模式
|
||||
* @param key 密钥值,明文
|
||||
* @param data 原始数据
|
||||
* @param key 密钥值,明文
|
||||
* @param data 原始数据
|
||||
*/
|
||||
byte[] symEncrypt(KeyAlg alg, AlgMode mode, Padding padding, byte[] key, byte[] data);
|
||||
|
||||
byte[] symEncrypt(KeyAlg alg, byte[] key, byte[] data);
|
||||
|
||||
byte[] symEncrypt(AlgId alg, byte[] key, byte[] iv, byte[] data);
|
||||
|
||||
/**
|
||||
* 对称解密
|
||||
* @param alg 算法,只支持对称算法
|
||||
* @param key 密钥值,明文
|
||||
* @param mode 轮模式
|
||||
*
|
||||
* @param alg 算法,只支持对称算法
|
||||
* @param key 密钥值,明文
|
||||
* @param mode 轮模式
|
||||
* @param padding 填充模式
|
||||
* @param data 密文数据
|
||||
* @param data 密文数据
|
||||
*/
|
||||
byte[] symDecrypt(KeyAlg alg, AlgMode mode, Padding padding, byte[] key, byte[] data);
|
||||
|
||||
byte[] symDecrypt(KeyAlg alg, byte[] key, byte[] data);
|
||||
|
||||
|
||||
byte[] symDecrypt(AlgId alg, byte[] key, byte[] iv, byte[] data);
|
||||
|
||||
|
||||
/**
|
||||
|
||||
@@ -98,7 +98,7 @@ public class BcSdfApiAdaptor implements SdfApiAdapter {
|
||||
|
||||
@SneakyThrows
|
||||
@Override
|
||||
public EccKey generateKeyPairECC(String sessionHandle, String alg, int uiKeyBits) {
|
||||
public EccKey generateKeyPairECC(String sessionHandle, AlgId alg) {
|
||||
// 生成密钥对
|
||||
KeyPair keyPair = BCSM2Utils.generateKeyPair();
|
||||
BCECPublicKey pubKey = (BCECPublicKey) keyPair.getPublic();
|
||||
@@ -171,9 +171,14 @@ public class BcSdfApiAdaptor implements SdfApiAdapter {
|
||||
|
||||
|
||||
@Override
|
||||
@SneakyThrows
|
||||
public byte[] symEncrypt(String sessionHandle, String keyHandle, AlgId alg, byte[] pucIv, byte[] pucData) {
|
||||
byte[] symKey = getSymKey(keyHandle);
|
||||
return externalSymEncrypt(sessionHandle, symKey, alg, pucIv, pucData);
|
||||
}
|
||||
|
||||
@Override
|
||||
@SneakyThrows
|
||||
public byte[] externalSymEncrypt(String sessionHandle, byte[] symKey, AlgId alg, byte[] pucIv, byte[] pucData) {
|
||||
switch (alg) {
|
||||
case SGD_SM4_ECB:
|
||||
return BCSM4Utils.encrypt_ECB_NoPadding(symKey, pucData);
|
||||
@@ -185,9 +190,14 @@ public class BcSdfApiAdaptor implements SdfApiAdapter {
|
||||
}
|
||||
|
||||
@Override
|
||||
@SneakyThrows
|
||||
public byte[] symDecrypt(String sessionHandle, String keyHandle, AlgId alg, byte[] pucIv, byte[] pucEncData) {
|
||||
byte[] symKey = getSymKey(keyHandle);
|
||||
return externalSymDecrypt(sessionHandle, symKey, alg, pucIv, pucEncData);
|
||||
}
|
||||
|
||||
@Override
|
||||
@SneakyThrows
|
||||
public byte[] externalSymDecrypt(String sessionHandle, byte[] symKey, AlgId alg, byte[] pucIv, byte[] pucEncData) {
|
||||
switch (alg) {
|
||||
case SGD_SM4_ECB:
|
||||
return BCSM4Utils.decrypt_ECB_NoPadding(symKey, pucEncData);
|
||||
|
||||
@@ -8,6 +8,7 @@ import com.sunyard.chsm.sdf.lib.SdfLibrary;
|
||||
import com.sunyard.chsm.sdf.model.DeviceInfo;
|
||||
import com.sunyard.chsm.sdf.model.EccCipher;
|
||||
import com.sunyard.chsm.sdf.model.EccKey;
|
||||
import com.sunyard.chsm.sdf.model.EccPriKey;
|
||||
import com.sunyard.chsm.sdf.model.EccPubKey;
|
||||
import com.sunyard.chsm.sdf.model.SDF_DeviceInfo;
|
||||
import com.sunyard.chsm.sdf.util.LangUtils;
|
||||
@@ -129,8 +130,13 @@ public abstract class JnaSdfAdaptor implements SdfApiAdapter {
|
||||
}
|
||||
|
||||
@Override
|
||||
public EccKey generateKeyPairECC(String sessionHandle, String alg, int uiKeyBits) {
|
||||
return null;
|
||||
public EccKey generateKeyPairECC(String sessionHandle, AlgId alg) {
|
||||
byte[] sdfPubKey = new byte[132];
|
||||
byte[] sdfPriKey = new byte[68];
|
||||
|
||||
Pointer hSessionHandle = getSessionHandle(sessionHandle);
|
||||
sdfLibrary.SDF_GenerateKeyPair_ECC(hSessionHandle, getAlgId(alg), 256, sdfPubKey, sdfPriKey);
|
||||
return new EccKey(EccPubKey.fromBytes(sdfPubKey).getPubKeyBytes(), EccPriKey.fromBytes(sdfPriKey).getD());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -200,6 +206,25 @@ public abstract class JnaSdfAdaptor implements SdfApiAdapter {
|
||||
return pucEncData;
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] externalSymEncrypt(String sessionHandle, byte[] symKey, AlgId alg, byte[] pucIv, byte[] pucData) {
|
||||
int uiDataLength = pucData.length;
|
||||
byte[] pucEncData = new byte[uiDataLength];
|
||||
Pointer hSessionHandle = getSessionHandle(sessionHandle);
|
||||
int length = symKey.length;
|
||||
PointerByReference phKeyHandle = new PointerByReference();
|
||||
// 先导入密钥
|
||||
sdfLibrary.SDF_ImportKey(hSessionHandle, symKey, length, phKeyHandle);
|
||||
//加密
|
||||
Pointer hKeyHandle = phKeyHandle.getValue();
|
||||
IntByReference puiLength = new IntByReference();
|
||||
sdfLibrary.SDF_Encrypt(hSessionHandle, hKeyHandle, getAlgId(alg),
|
||||
pucIv, pucData, uiDataLength, pucEncData, puiLength);
|
||||
// 使用后销毁密钥
|
||||
sdfLibrary.SDF_DestroyKey(hSessionHandle, hKeyHandle);
|
||||
return pucEncData;
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] symDecrypt(String sessionHandle, String keyHandle, AlgId alg, byte[] pucIv, byte[] pucEncData) {
|
||||
Pointer hSessionHandle = getSessionHandle(sessionHandle);
|
||||
@@ -212,4 +237,24 @@ public abstract class JnaSdfAdaptor implements SdfApiAdapter {
|
||||
pucIv, pucEncData, uiEncDataLength, pucData, puiLength);
|
||||
return pucData;
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] externalSymDecrypt(String sessionHandle, byte[] symKey, AlgId alg, byte[] pucIv, byte[] pucEncData) {
|
||||
int uiEncDataLength = pucEncData.length;
|
||||
byte[] pucData = new byte[uiEncDataLength];
|
||||
|
||||
PointerByReference phKeyHandle = new PointerByReference();
|
||||
Pointer hSessionHandle = getSessionHandle(sessionHandle);
|
||||
int length = symKey.length;
|
||||
// 导入会话密钥
|
||||
sdfLibrary.SDF_ImportKey(hSessionHandle, symKey, length, phKeyHandle);
|
||||
// 解密
|
||||
Pointer hKeyHandle = phKeyHandle.getValue();
|
||||
IntByReference puiLength = new IntByReference();
|
||||
sdfLibrary.SDF_Decrypt(hSessionHandle, hKeyHandle, getAlgId(alg),
|
||||
pucIv, pucEncData, uiEncDataLength, pucData, puiLength);
|
||||
// 销毁会话密钥
|
||||
sdfLibrary.SDF_DestroyKey(hSessionHandle, hKeyHandle);
|
||||
return pucData;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -51,7 +51,7 @@ public interface SdfApiAdapter {
|
||||
* @return pucRandom 返回随机数
|
||||
*/
|
||||
byte[] generateRandom(String sessionHandle, int uiLength);
|
||||
|
||||
|
||||
/**
|
||||
* 导出ECC加密公钥
|
||||
*
|
||||
@@ -61,13 +61,12 @@ public interface SdfApiAdapter {
|
||||
EccPubKey exportEncPublicKeyECC(String sessionHandle, int uiKeyIndex);
|
||||
|
||||
/**
|
||||
* 产生ECC密钥对并输出
|
||||
* 产生ECC密钥对并输出 密钥模长 256
|
||||
*
|
||||
* @param alg 指定算法标识 SGD_SM2_1
|
||||
* @param uiKeyBits 指定密钥模长
|
||||
* @return pucPublicKeyEcc 返回公钥 | pucPrivateKeyEcc 返回私钥
|
||||
*/
|
||||
EccKey generateKeyPairECC(String sessionHandle, String alg, int uiKeyBits);
|
||||
EccKey generateKeyPairECC(String sessionHandle, AlgId alg);
|
||||
|
||||
boolean getPrivateKeyAccessRight(String hSessionHandle, int uiKeyIndex, byte[] pucPassword);
|
||||
|
||||
@@ -75,7 +74,7 @@ public interface SdfApiAdapter {
|
||||
* 导入会话密钥并用内部ECC私钥解密
|
||||
*
|
||||
* @param uiIskIndex 密码设备内部存储加密私钥的索引值,对应于加密时的公钥
|
||||
* @param eccCipher 缓冲区指针,用于存放返回的密钥密文
|
||||
* @param eccCipher 缓冲区指针,用于存放返回的密钥密文
|
||||
* @return phKeyHandle 返回密钥句柄
|
||||
*/
|
||||
String importKeyWithISKECC(String sessionHandle, int uiIskIndex, EccCipher eccCipher);
|
||||
@@ -103,8 +102,8 @@ public interface SdfApiAdapter {
|
||||
/**
|
||||
* 外部密钥ECC公钥加密
|
||||
*
|
||||
* @param pubKey 外部ECC公钥结构
|
||||
* @param pucData 缓冲区指针,用于存放外部输入的数据
|
||||
* @param pubKey 外部ECC公钥结构
|
||||
* @param pucData 缓冲区指针,用于存放外部输入的数据
|
||||
* @return pucEncData 返回数据密文
|
||||
*/
|
||||
EccCipher externalEncryptECC(String sessionHandle, EccPubKey pubKey, byte[] pucData);
|
||||
@@ -121,6 +120,8 @@ public interface SdfApiAdapter {
|
||||
*/
|
||||
byte[] symEncrypt(String sessionHandle, String keyHandle, AlgId alg, byte[] pucIv, byte[] pucData);
|
||||
|
||||
byte[] externalSymEncrypt(String sessionHandle, byte[] symKey, AlgId alg, byte[] pucIv, byte[] pucData);
|
||||
|
||||
/**
|
||||
* 对称解密
|
||||
*
|
||||
@@ -133,4 +134,5 @@ public interface SdfApiAdapter {
|
||||
*/
|
||||
byte[] symDecrypt(String sessionHandle, String keyHandle, AlgId alg, byte[] pucIv, byte[] pucEncData);
|
||||
|
||||
byte[] externalSymDecrypt(String sessionHandle, byte[] symKey, AlgId alg, byte[] pucIv, byte[] pucEncData);
|
||||
}
|
||||
|
||||
@@ -13,6 +13,10 @@ import java.util.Objects;
|
||||
public class SdfApiAdapterFactory {
|
||||
|
||||
|
||||
public static SdfApiAdapter getBcAdapter() {
|
||||
return BcSdfApiAdaptor.INSTANCE;
|
||||
}
|
||||
|
||||
public static SdfApiAdapter newInstance(String model, String ip, Integer port) {
|
||||
|
||||
Assert.hasText(model, "设备型号不能为空");
|
||||
@@ -31,7 +35,4 @@ public class SdfApiAdapterFactory {
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -221,7 +221,7 @@ public interface SdfLibrary extends Library {
|
||||
* @param phKeyhandle
|
||||
* @return
|
||||
*/
|
||||
int SDF_DestroyKey(Pointer phSessionHandle, PointerByReference phKeyhandle);
|
||||
int SDF_DestroyKey(Pointer phSessionHandle, Pointer phKeyhandle);
|
||||
|
||||
|
||||
/**
|
||||
|
||||
@@ -3,6 +3,10 @@ package com.sunyard.chsm.sdf.model;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* @author liulu
|
||||
@@ -18,5 +22,17 @@ public class EccPriKey {
|
||||
// 私 钥
|
||||
private byte[] D;
|
||||
|
||||
public static EccPriKey fromBytes(byte[] priKey) {
|
||||
Assert.notNull(priKey, "公钥数据不能为null");
|
||||
if (Objects.equals(priKey.length, 132)) {
|
||||
// 00010000
|
||||
priKey = Arrays.copyOfRange(priKey, 4, priKey.length);
|
||||
}
|
||||
Assert.isTrue(Objects.equals(priKey.length, 32) || Objects.equals(priKey.length, 64), "Ecc私钥数据格式错误");
|
||||
if (Objects.equals(priKey.length, 32)) {
|
||||
return new EccPriKey(256, priKey);
|
||||
}
|
||||
return new EccPriKey(256, Arrays.copyOfRange(priKey, 32, 64));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -30,7 +30,7 @@ public abstract class PaddingUtil {
|
||||
}
|
||||
}
|
||||
|
||||
public static byte[] PKCS5Padding(byte[] content) throws Exception {
|
||||
public static byte[] PKCS5Padding(byte[] content) {
|
||||
return PKCS7Padding(content, 8);
|
||||
}
|
||||
|
||||
|
||||
@@ -187,7 +187,7 @@ public class TmkService {
|
||||
log.warn("data error, no tmk found in system");
|
||||
return;
|
||||
}
|
||||
SdfApiAdapter softAdapter = SdfApiAdapterFactory.newInstance(BouncyCastleProvider.PROVIDER_NAME, "", 0);
|
||||
SdfApiAdapter softAdapter = SdfApiAdapterFactory.getBcAdapter();
|
||||
EccPubKey pubKey = softAdapter.exportEncPublicKeyECC("", 1);
|
||||
|
||||
SdfApiAdapter tmkAdapter = SdfApiAdapterFactory.newInstance(device.getManufacturerModel(), device.getServiceIp(), device.getServicePort());
|
||||
@@ -244,7 +244,7 @@ public class TmkService {
|
||||
}
|
||||
}
|
||||
|
||||
private byte[] getSoftDeviceEncTmk() {
|
||||
public byte[] getSoftDeviceEncTmk() {
|
||||
boolean tmkInit = isTmkInit();
|
||||
Assert.isTrue(tmkInit, "主密钥未初始化");
|
||||
boolean enabled = isEnableSoftDevice();
|
||||
|
||||
Reference in New Issue
Block a user