主密钥同步

This commit is contained in:
liulu
2024-12-09 17:15:57 +08:00
parent 258cd3ed81
commit f4361d2fd5
6 changed files with 216 additions and 87 deletions
@@ -8,17 +8,23 @@ import com.sunyard.chsm.sdf.model.EccPubKey;
import com.sunyard.chsm.sdf.util.LangUtils;
import com.sunyard.chsm.utils.gm.BCECUtils;
import com.sunyard.chsm.utils.gm.BCSM2Utils;
import com.sunyard.chsm.utils.gm.BCSM4Utils;
import lombok.SneakyThrows;
import org.bouncycastle.crypto.InvalidCipherTextException;
import org.bouncycastle.crypto.params.ECPrivateKeyParameters;
import org.bouncycastle.crypto.params.ECPublicKeyParameters;
import org.bouncycastle.jcajce.provider.asymmetric.ec.BCECPrivateKey;
import org.bouncycastle.jcajce.provider.asymmetric.ec.BCECPublicKey;
import org.bouncycastle.math.ec.ECPoint;
import org.bouncycastle.util.BigIntegers;
import org.springframework.util.Assert;
import java.math.BigInteger;
import java.security.KeyPair;
import java.security.SecureRandom;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
/**
* @author liulu
@@ -26,6 +32,7 @@ import java.security.SecureRandom;
*/
public class BcSdfApiAdaptor implements SdfApiAdapter {
protected static final Map<String, byte[]> KEY_HANDLE_CONTEXT = new ConcurrentHashMap<>();
private static final DeviceInfo deviceInfo;
@@ -41,6 +48,8 @@ public class BcSdfApiAdaptor implements SdfApiAdapter {
deviceInfo.setHashAlgAbility(7010608454676760881L);
}
protected static final BcSdfApiAdaptor INSTANCE = new BcSdfApiAdaptor();
@Override
public String openDevice() {
return "c95a78d9c04a557b7b46dbcb5f36cc66";
@@ -102,38 +111,58 @@ public class BcSdfApiAdaptor implements SdfApiAdapter {
@Override
public boolean getPrivateKeyAccessRight(String hSessionHandle, int uiKeyIndex, byte[] pucPassword) {
return false;
return true;
}
@Override
public EccCipher exchangeDigitEnvelopeBaseOnECC(String sessionHandle, int uiKeyIndex, EccPubKey pubKey, EccCipher pucEncDateIn) {
return null;
ECPublicKeyParameters pub = BCECUtils.createECPublicKeyParameters(pubKey.getX(), pubKey.getY());
ECPrivateKeyParameters pri = BCECUtils.createECPrivateKeyParameters(getD());
try {
byte[] k = BCSM2Utils.decrypt(pri, pucEncDateIn.getC1C3C2Bytes());
byte[] encrypt = BCSM2Utils.encrypt(pub, k);
return EccCipher.fromBytes(encrypt);
} catch (InvalidCipherTextException e) {
throw new IllegalArgumentException(e);
}
}
@Override
public String importKeyWithISKECC(String sessionHandle, int uiIskIndex, EccCipher eccCipher) {
return "";
ECPrivateKeyParameters pri = BCECUtils.createECPrivateKeyParameters(getD());
try {
byte[] pucKey = BCSM2Utils.decrypt(pri, eccCipher.getC1C3C2Bytes());
Assert.isTrue(pucKey.length == 16, "密钥长度错误");
String key = UUID.randomUUID().toString();
KEY_HANDLE_CONTEXT.put(key, pucKey);
return key;
} catch (InvalidCipherTextException e) {
throw new IllegalArgumentException(e);
}
}
@Override
public String importKey(String sessionHandle, byte[] pucKey) {
return "";
Assert.isTrue(pucKey.length == 16, "密钥长度错误");
String key = UUID.randomUUID().toString();
KEY_HANDLE_CONTEXT.put(key, pucKey);
return key;
}
@Override
public int destroyKey(String sessionHandle, String hKeyHandle) {
KEY_HANDLE_CONTEXT.remove(hKeyHandle);
return 0;
}
@Override
public EccCipher externalEncryptECC(String sessionHandle, EccPubKey pubKey, byte[] pucData) {
ECPublicKeyParameters parameters = BCECUtils.createECPublicKeyParameters(
pubKey.getX(),
pubKey.getY()
);
ECPublicKeyParameters pub = BCECUtils.createECPublicKeyParameters(pubKey.getX(), pubKey.getY());
try {
byte[] encrypt = BCSM2Utils.encrypt(parameters, pucData);
byte[] encrypt = BCSM2Utils.encrypt(pub, pucData);
return EccCipher.fromBytes(encrypt);
} catch (InvalidCipherTextException e) {
throw new IllegalArgumentException(e);
@@ -142,12 +171,36 @@ public class BcSdfApiAdaptor implements SdfApiAdapter {
@Override
@SneakyThrows
public byte[] symEncrypt(String sessionHandle, String keyHandle, AlgId alg, byte[] pucIv, byte[] pucData) {
return new byte[0];
byte[] symKey = getSymKey(keyHandle);
switch (alg) {
case SGD_SM4_ECB:
return BCSM4Utils.encrypt_ECB_NoPadding(symKey, pucData);
case SGD_SM4_CBC:
return BCSM4Utils.encrypt_CBC_NoPadding(symKey, pucIv, pucData);
default:
throw new IllegalArgumentException("不支持的算法:" + alg.name());
}
}
@Override
@SneakyThrows
public byte[] symDecrypt(String sessionHandle, String keyHandle, AlgId alg, byte[] pucIv, byte[] pucEncData) {
return new byte[0];
byte[] symKey = getSymKey(keyHandle);
switch (alg) {
case SGD_SM4_ECB:
return BCSM4Utils.decrypt_ECB_NoPadding(symKey, pucEncData);
case SGD_SM4_CBC:
return BCSM4Utils.decrypt_CBC_NoPadding(symKey, pucIv, pucEncData);
default:
throw new IllegalArgumentException("不支持的算法:" + alg.name());
}
}
protected byte[] getSymKey(String keyHandle) {
byte[] key = KEY_HANDLE_CONTEXT.get(keyHandle);
Assert.notNull(key, "密钥句柄不存在");
return key;
}
}
@@ -20,7 +20,7 @@ public class SdfApiAdapterFactory {
if (Objects.isNull(modelEnum) && Objects.equals(BouncyCastleProvider.PROVIDER_NAME, model)) {
// bc adaptor
return new BcSdfApiAdaptor();
return BcSdfApiAdaptor.INSTANCE;
}
switch (modelEnum) {
case enc001:
@@ -1,5 +1,6 @@
package com.sunyard.chsm.sdf.model;
import com.sunyard.chsm.utils.CodecUtils;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@@ -30,6 +31,9 @@ public class EccCipher {
// 密文数据
private byte[] C;
public String getC1C3C2Hex() {
return CodecUtils.encodeHex(getC1C3C2Bytes());
}
public byte[] getC1C3C2Bytes() {
int xLen = x.length;
@@ -57,6 +61,10 @@ public class EccCipher {
return d;
}
public static EccCipher fromHex(String hex) {
return fromBytes(CodecUtils.decodeHex(hex));
}
public static EccCipher fromBytes(byte[] cipher) {
Assert.notNull(cipher, "Ecc密文数据不能为null");
if (cipher[0] == 0x04) {