sdf
This commit is contained in:
parent
b87165b850
commit
0f61f4be5b
@ -1,7 +1,10 @@
|
|||||||
package com.sunyard.chsm.sdf.adapter;
|
package com.sunyard.chsm.sdf.adapter;
|
||||||
|
|
||||||
|
import com.sunyard.chsm.sdf.context.AlgId;
|
||||||
import com.sunyard.chsm.sdf.model.DeviceInfo;
|
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.EccKey;
|
||||||
|
import com.sunyard.chsm.sdf.model.EccPubKey;
|
||||||
import com.sunyard.chsm.sdf.util.LangUtils;
|
import com.sunyard.chsm.sdf.util.LangUtils;
|
||||||
import com.sunyard.chsm.utils.gm.BCECUtils;
|
import com.sunyard.chsm.utils.gm.BCECUtils;
|
||||||
import com.sunyard.chsm.utils.gm.BCSM2Utils;
|
import com.sunyard.chsm.utils.gm.BCSM2Utils;
|
||||||
@ -11,7 +14,6 @@ import org.bouncycastle.crypto.params.ECPublicKeyParameters;
|
|||||||
import org.bouncycastle.jcajce.provider.asymmetric.ec.BCECPrivateKey;
|
import org.bouncycastle.jcajce.provider.asymmetric.ec.BCECPrivateKey;
|
||||||
import org.bouncycastle.jcajce.provider.asymmetric.ec.BCECPublicKey;
|
import org.bouncycastle.jcajce.provider.asymmetric.ec.BCECPublicKey;
|
||||||
import org.bouncycastle.math.ec.ECPoint;
|
import org.bouncycastle.math.ec.ECPoint;
|
||||||
import org.bouncycastle.util.Arrays;
|
|
||||||
import org.bouncycastle.util.BigIntegers;
|
import org.bouncycastle.util.BigIntegers;
|
||||||
|
|
||||||
import java.math.BigInteger;
|
import java.math.BigInteger;
|
||||||
@ -72,10 +74,10 @@ public class BcSdfApiAdaptor implements SdfApiAdapter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public byte[] exportEncPublicKeyECC(String sessionHandle, int uiKeyIndex) {
|
public EccPubKey exportEncPublicKeyECC(String sessionHandle, int uiKeyIndex) {
|
||||||
BigInteger d = new BigInteger(1, getD());
|
BigInteger d = new BigInteger(1, getD());
|
||||||
ECPoint q = BCSM2Utils.G_POINT.multiply(d).normalize();
|
ECPoint q = BCSM2Utils.G_POINT.multiply(d).normalize();
|
||||||
return LangUtils.merge(q.getXCoord().getEncoded(), q.getYCoord().getEncoded());
|
return new EccPubKey(256, q.getXCoord().getEncoded(), q.getYCoord().getEncoded());
|
||||||
}
|
}
|
||||||
|
|
||||||
private byte[] getD() {
|
private byte[] getD() {
|
||||||
@ -99,26 +101,53 @@ public class BcSdfApiAdaptor implements SdfApiAdapter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public byte[] exchangeDigitEnvelopeBaseOnECC(String sessionHandle, int uiKeyIndex, byte[] pubKey, byte[] pucEncDateIn) {
|
public boolean getPrivateKeyAccessRight(String hSessionHandle, int uiKeyIndex, byte[] pucPassword) {
|
||||||
return new byte[0];
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public byte[] externalEncryptECC(String sessionHandle, byte[] pubKey, byte[] pucData) {
|
public EccCipher exchangeDigitEnvelopeBaseOnECC(String sessionHandle, int uiKeyIndex, EccPubKey pubKey, EccCipher pucEncDateIn) {
|
||||||
if (pubKey[0] == 4) {
|
return null;
|
||||||
pubKey = Arrays.copyOfRange(pubKey, 1, 65);
|
}
|
||||||
}
|
|
||||||
|
@Override
|
||||||
|
public String importKeyWithISKECC(String sessionHandle, int uiIskIndex, EccCipher eccCipher) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String importKey(String sessionHandle, byte[] pucKey) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int destroyKey(String sessionHandle, String hKeyHandle) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public EccCipher externalEncryptECC(String sessionHandle, EccPubKey pubKey, byte[] pucData) {
|
||||||
ECPublicKeyParameters parameters = BCECUtils.createECPublicKeyParameters(
|
ECPublicKeyParameters parameters = BCECUtils.createECPublicKeyParameters(
|
||||||
Arrays.copyOfRange(pubKey, 0, 32),
|
pubKey.getX(),
|
||||||
Arrays.copyOfRange(pubKey, 32, 64)
|
pubKey.getY()
|
||||||
);
|
);
|
||||||
try {
|
try {
|
||||||
byte[] encrypt = BCSM2Utils.encrypt(parameters, pucData);
|
byte[] encrypt = BCSM2Utils.encrypt(parameters, pucData);
|
||||||
return Arrays.copyOfRange(encrypt, 1, encrypt.length);
|
return EccCipher.fromBytes(encrypt);
|
||||||
} catch (InvalidCipherTextException e) {
|
} catch (InvalidCipherTextException e) {
|
||||||
throw new IllegalArgumentException(e);
|
throw new IllegalArgumentException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public byte[] symEncrypt(String sessionHandle, String keyHandle, AlgId alg, byte[] pucIv, byte[] pucData) {
|
||||||
|
return new byte[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public byte[] symDecrypt(String sessionHandle, String keyHandle, AlgId alg, byte[] pucIv, byte[] pucEncData) {
|
||||||
|
return new byte[0];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,18 +1,21 @@
|
|||||||
package com.sunyard.chsm.sdf.adapter;
|
package com.sunyard.chsm.sdf.adapter;
|
||||||
|
|
||||||
import com.sun.jna.Pointer;
|
import com.sun.jna.Pointer;
|
||||||
|
import com.sun.jna.ptr.IntByReference;
|
||||||
import com.sun.jna.ptr.PointerByReference;
|
import com.sun.jna.ptr.PointerByReference;
|
||||||
import com.sunyard.chsm.sdf.context.AlgId;
|
import com.sunyard.chsm.sdf.context.AlgId;
|
||||||
import com.sunyard.chsm.sdf.lib.SdfLibrary;
|
import com.sunyard.chsm.sdf.lib.SdfLibrary;
|
||||||
import com.sunyard.chsm.sdf.model.DeviceInfo;
|
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.EccKey;
|
||||||
|
import com.sunyard.chsm.sdf.model.EccPubKey;
|
||||||
import com.sunyard.chsm.sdf.model.SDF_DeviceInfo;
|
import com.sunyard.chsm.sdf.model.SDF_DeviceInfo;
|
||||||
import com.sunyard.chsm.sdf.util.LangUtils;
|
import com.sunyard.chsm.sdf.util.LangUtils;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.bouncycastle.util.encoders.Hex;
|
||||||
import org.springframework.util.Assert;
|
import org.springframework.util.Assert;
|
||||||
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
@ -98,9 +101,9 @@ public abstract class JnaSdfAdaptor implements SdfApiAdapter {
|
|||||||
sdfLibrary.SDF_GetDeviceInfo(getSessionHandle(sessionHandle), sdfInfo);
|
sdfLibrary.SDF_GetDeviceInfo(getSessionHandle(sessionHandle), sdfInfo);
|
||||||
|
|
||||||
DeviceInfo deviceInfo = new DeviceInfo();
|
DeviceInfo deviceInfo = new DeviceInfo();
|
||||||
deviceInfo.setIssuerName(new String(sdfInfo.IssuerName));
|
deviceInfo.setIssuerName(new String(LangUtils.removeLastZero(sdfInfo.IssuerName)));
|
||||||
deviceInfo.setDeviceName(new String(sdfInfo.DeviceName));
|
deviceInfo.setDeviceName(new String(LangUtils.removeLastZero(sdfInfo.DeviceName)));
|
||||||
deviceInfo.setDeviceSerial(new String(sdfInfo.DeviceSerial));
|
deviceInfo.setDeviceSerial(new String(LangUtils.removeLastZero(sdfInfo.DeviceSerial)));
|
||||||
deviceInfo.setDeviceVersion(sdfInfo.DeviceVersion);
|
deviceInfo.setDeviceVersion(sdfInfo.DeviceVersion);
|
||||||
deviceInfo.setStandardVersion(sdfInfo.StandardVersion);
|
deviceInfo.setStandardVersion(sdfInfo.StandardVersion);
|
||||||
deviceInfo.setAsymAlgAbility(new long[]{sdfInfo.AsymAlgAbility[0], sdfInfo.AsymAlgAbility[1]});
|
deviceInfo.setAsymAlgAbility(new long[]{sdfInfo.AsymAlgAbility[0], sdfInfo.AsymAlgAbility[1]});
|
||||||
@ -119,11 +122,12 @@ public abstract class JnaSdfAdaptor implements SdfApiAdapter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public byte[] exportEncPublicKeyECC(String sessionHandle, int uiKeyIndex) {
|
public EccPubKey exportEncPublicKeyECC(String sessionHandle, int uiKeyIndex) {
|
||||||
byte[] pubKey = new byte[132];
|
byte[] pubKey = new byte[132];
|
||||||
Pointer hSessionHandle = getSessionHandle(sessionHandle);
|
Pointer hSessionHandle = getSessionHandle(sessionHandle);
|
||||||
sdfLibrary.SDF_ExportEncPublicKey_ECC(hSessionHandle, uiKeyIndex, pubKey);
|
sdfLibrary.SDF_ExportEncPublicKey_ECC(hSessionHandle, uiKeyIndex, pubKey);
|
||||||
return LangUtils.merge(Arrays.copyOfRange(pubKey, 36, 68), Arrays.copyOfRange(pubKey, 100, 132));
|
log.info("sdf pubkey: {}", Hex.toHexString(pubKey));
|
||||||
|
return EccPubKey.fromBytes(pubKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -132,15 +136,86 @@ public abstract class JnaSdfAdaptor implements SdfApiAdapter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public byte[] exchangeDigitEnvelopeBaseOnECC(String sessionHandle, int uiKeyIndex, byte[] pubKey, byte[] pucEncDateIn) {
|
public boolean getPrivateKeyAccessRight(String sessionHandle, int uiKeyIndex, byte[] pucPassword) {
|
||||||
return new byte[0];
|
Pointer hSessionHandle = getSessionHandle(sessionHandle);
|
||||||
|
int res = sdfLibrary.SDF_GetPrivateKeyAccessRight(hSessionHandle, uiKeyIndex, pucPassword, pucPassword.length);
|
||||||
|
log.info("SDF_GetPrivateKeyAccessRight: {}, {}", res, Integer.toHexString(res));
|
||||||
|
return res == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public byte[] externalEncryptECC(String sessionHandle, byte[] pubKey, byte[] pucData) {
|
public String importKeyWithISKECC(String sessionHandle, int uiIskIndex, EccCipher eccCipher) {
|
||||||
|
Pointer hSessionHandle = getSessionHandle(sessionHandle);
|
||||||
|
PointerByReference phKeyHandle = new PointerByReference();
|
||||||
|
|
||||||
|
int res = sdfLibrary.SDF_ImportKeyWithISK_ECC(hSessionHandle, uiIskIndex, eccCipher.toSdfData(), phKeyHandle);
|
||||||
|
log.info("SDF_ImportKeyWithISK_ECC: {}, {}", res, Integer.toHexString(res));
|
||||||
|
String key = UUID.randomUUID().toString();
|
||||||
|
KEY_HANDLE_CONTEXT.put(key, phKeyHandle.getValue());
|
||||||
|
return key;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String importKey(String sessionHandle, byte[] pucKey) {
|
||||||
|
Pointer hSessionHandle = getSessionHandle(sessionHandle);
|
||||||
|
PointerByReference phKeyHandle = new PointerByReference();
|
||||||
|
sdfLibrary.SDF_ImportKey(hSessionHandle, pucKey, pucKey.length, phKeyHandle);
|
||||||
|
String key = UUID.randomUUID().toString();
|
||||||
|
KEY_HANDLE_CONTEXT.put(key, phKeyHandle.getValue());
|
||||||
|
return key;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int destroyKey(String sessionHandle, String hKeyHandle) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public EccCipher exchangeDigitEnvelopeBaseOnECC(String sessionHandle, int uiKeyIndex, EccPubKey pubKey, EccCipher pucEncDateIn) {
|
||||||
|
Pointer hSessionHandle = getSessionHandle(sessionHandle);
|
||||||
|
|
||||||
|
byte[] pucEncDateOut = new byte[164 + pucEncDateIn.getL()];
|
||||||
|
int res = sdfLibrary.SDF_ExchangeDigitEnvelopeBaseOnECC(hSessionHandle, uiKeyIndex, getAlgId(AlgId.SGD_SM2_1),
|
||||||
|
pubKey.toSdfData(), pucEncDateIn.toSdfData(), pucEncDateOut);
|
||||||
|
log.info("SDF_ExchangeDigitEnvelopeBaseOnECC: {}, {}", res, Integer.toHexString(res));
|
||||||
|
return EccCipher.fromBytes(pucEncDateOut);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public EccCipher externalEncryptECC(String sessionHandle, EccPubKey pubKey, byte[] pucData) {
|
||||||
byte[] encData = new byte[128 + 32 + 4 + pucData.length];
|
byte[] encData = new byte[128 + 32 + 4 + pucData.length];
|
||||||
Pointer hSessionHandle = getSessionHandle(sessionHandle);
|
Pointer hSessionHandle = getSessionHandle(sessionHandle);
|
||||||
sdfLibrary.SDF_ExternalEncrypt_ECC(hSessionHandle, getAlgId(AlgId.SGD_SM2_3), pubKey, pucData, pucData.length, encData);
|
sdfLibrary.SDF_ExternalEncrypt_ECC(hSessionHandle, getAlgId(AlgId.SGD_SM2_3), pubKey.toSdfData(), pucData, pucData.length, encData);
|
||||||
return encData;
|
log.info("sdfEncryptECC: {}", Hex.toHexString(encData));
|
||||||
|
return EccCipher.fromBytes(encData);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public byte[] symEncrypt(String sessionHandle, String keyHandle, AlgId alg, byte[] pucIv, byte[] pucData) {
|
||||||
|
|
||||||
|
Pointer hSessionHandle = getSessionHandle(sessionHandle);
|
||||||
|
Pointer hKeyHandle = getKeyHandle(keyHandle);
|
||||||
|
int uiDataLength = pucData.length;
|
||||||
|
byte[] pucEncData = new byte[uiDataLength];
|
||||||
|
IntByReference puiLength = new IntByReference();
|
||||||
|
//加密
|
||||||
|
sdfLibrary.SDF_Encrypt(hSessionHandle, hKeyHandle, getAlgId(alg),
|
||||||
|
pucIv, pucData, uiDataLength, pucEncData, puiLength);
|
||||||
|
|
||||||
|
return pucEncData;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public byte[] symDecrypt(String sessionHandle, String keyHandle, AlgId alg, byte[] pucIv, byte[] pucEncData) {
|
||||||
|
Pointer hSessionHandle = getSessionHandle(sessionHandle);
|
||||||
|
Pointer hKeyHandle = getKeyHandle(keyHandle);
|
||||||
|
int uiEncDataLength = pucEncData.length;
|
||||||
|
byte[] pucData = new byte[uiEncDataLength];
|
||||||
|
//解密
|
||||||
|
IntByReference puiLength = new IntByReference();
|
||||||
|
sdfLibrary.SDF_Decrypt(hSessionHandle, hKeyHandle, getAlgId(alg),
|
||||||
|
pucIv, pucEncData, uiEncDataLength, pucData, puiLength);
|
||||||
|
return pucData;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,10 @@
|
|||||||
package com.sunyard.chsm.sdf.adapter;
|
package com.sunyard.chsm.sdf.adapter;
|
||||||
|
|
||||||
|
import com.sunyard.chsm.sdf.context.AlgId;
|
||||||
import com.sunyard.chsm.sdf.model.DeviceInfo;
|
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.EccKey;
|
||||||
|
import com.sunyard.chsm.sdf.model.EccPubKey;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author liulu
|
* @author liulu
|
||||||
@ -55,7 +58,7 @@ public interface SdfApiAdapter {
|
|||||||
* @param uiKeyIndex 密码设备存储的ECC密钥对索引值
|
* @param uiKeyIndex 密码设备存储的ECC密钥对索引值
|
||||||
* @return pucPublicKeyEcc 返回ECC加密公钥x+y
|
* @return pucPublicKeyEcc 返回ECC加密公钥x+y
|
||||||
*/
|
*/
|
||||||
byte[] exportEncPublicKeyECC(String sessionHandle, int uiKeyIndex);
|
EccPubKey exportEncPublicKeyECC(String sessionHandle, int uiKeyIndex);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 产生ECC密钥对并输出
|
* 产生ECC密钥对并输出
|
||||||
@ -66,11 +69,68 @@ public interface SdfApiAdapter {
|
|||||||
*/
|
*/
|
||||||
EccKey generateKeyPairECC(String sessionHandle, String alg, int uiKeyBits);
|
EccKey generateKeyPairECC(String sessionHandle, String alg, int uiKeyBits);
|
||||||
|
|
||||||
|
boolean getPrivateKeyAccessRight(String hSessionHandle, int uiKeyIndex, byte[] pucPassword);
|
||||||
|
|
||||||
byte[] exchangeDigitEnvelopeBaseOnECC(String sessionHandle, int uiKeyIndex, byte[] pubKey, byte[] pucEncDateIn);
|
/**
|
||||||
|
* 导入会话密钥并用内部ECC私钥解密
|
||||||
|
*
|
||||||
|
* @param uiIskIndex 密码设备内部存储加密私钥的索引值,对应于加密时的公钥
|
||||||
|
* @param eccCipher 缓冲区指针,用于存放返回的密钥密文
|
||||||
|
* @return phKeyHandle 返回密钥句柄
|
||||||
|
*/
|
||||||
|
String importKeyWithISKECC(String sessionHandle, int uiIskIndex, EccCipher eccCipher);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 导入明文会话密钥
|
||||||
|
*
|
||||||
|
* @param sessionHandle 与设备建立的会话句柄
|
||||||
|
* @param pucKey 缓冲区指针,用于存放输入的密钥密文
|
||||||
|
* @return phKeyHandle 返回密钥句柄
|
||||||
|
*/
|
||||||
|
String importKey(String sessionHandle, byte[] pucKey);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 销毁会话密钥
|
||||||
|
*
|
||||||
|
* @param hKeyHandle 密钥句柄
|
||||||
|
* @return 0 成功; 非0 失败,返回错误代码
|
||||||
|
*/
|
||||||
|
int destroyKey(String sessionHandle, String hKeyHandle);
|
||||||
|
|
||||||
|
|
||||||
byte[] externalEncryptECC(String sessionHandle, byte[] pubKey, byte[] pucData);
|
EccCipher exchangeDigitEnvelopeBaseOnECC(String sessionHandle, int uiKeyIndex, EccPubKey pubKey, EccCipher pucEncDateIn);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 外部密钥ECC公钥加密
|
||||||
|
*
|
||||||
|
* @param pubKey 外部ECC公钥结构
|
||||||
|
* @param pucData 缓冲区指针,用于存放外部输入的数据
|
||||||
|
* @return pucEncData 返回数据密文
|
||||||
|
*/
|
||||||
|
EccCipher externalEncryptECC(String sessionHandle, EccPubKey pubKey, byte[] pucData);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 对称加密
|
||||||
|
*
|
||||||
|
* @param sessionHandle 与设备建立的会话句柄
|
||||||
|
* @param keyHandle 指定的密钥句柄
|
||||||
|
* @param alg 算法标识,指定对称加密算法 SGD_SMS4_ECB
|
||||||
|
* @param pucIv IV数据
|
||||||
|
* @param pucData 数据明文
|
||||||
|
* @return 数据密文
|
||||||
|
*/
|
||||||
|
byte[] symEncrypt(String sessionHandle, String keyHandle, AlgId alg, byte[] pucIv, byte[] pucData);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 对称解密
|
||||||
|
*
|
||||||
|
* @param sessionHandle 与设备建立的会话句柄
|
||||||
|
* @param keyHandle 指定的密钥句柄
|
||||||
|
* @param alg 算法标识,指定对称加密算法 SGD_SMS4_ECB
|
||||||
|
* @param pucIv IV数据
|
||||||
|
* @param pucEncData 数据密文
|
||||||
|
* @return 数据明文
|
||||||
|
*/
|
||||||
|
byte[] symDecrypt(String sessionHandle, String keyHandle, AlgId alg, byte[] pucIv, byte[] pucEncData);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -24,6 +24,10 @@ public class SunyardJnaSdfAdaptor extends JnaSdfAdaptor {
|
|||||||
private final Integer connTimeout;
|
private final Integer connTimeout;
|
||||||
private final Integer dealTimeout;
|
private final Integer dealTimeout;
|
||||||
|
|
||||||
|
public SunyardJnaSdfAdaptor(String ip) {
|
||||||
|
this(ip, 8889, "sdf");
|
||||||
|
}
|
||||||
|
|
||||||
public SunyardJnaSdfAdaptor(String ip, int port) {
|
public SunyardJnaSdfAdaptor(String ip, int port) {
|
||||||
this(ip, port, "sdf");
|
this(ip, port, "sdf");
|
||||||
}
|
}
|
||||||
|
@ -179,6 +179,27 @@ public interface SdfLibrary extends Library {
|
|||||||
*/
|
*/
|
||||||
int SDF_ExchangeDigitEnvelopeBaseOnECC(Pointer hSessionHandle, int uiKeyIndex, int uiAlgID, byte[] pucPublicKey, byte[] pucEncDateIn, byte[] pucEncDateOut);
|
int SDF_ExchangeDigitEnvelopeBaseOnECC(Pointer hSessionHandle, int uiKeyIndex, int uiAlgID, byte[] pucPublicKey, byte[] pucEncDateIn, byte[] pucEncDateOut);
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param hSessionHandle 与设备建立的会话句柄
|
||||||
|
* @param pucKey 缓冲区指针,用于存放输入的密钥密文
|
||||||
|
* @param puiKeyLength 返回的密钥明文长度
|
||||||
|
* @param phKeyHandle 返回的密钥句柄
|
||||||
|
* @return 0 成功; 非0 失败,返回错误代码
|
||||||
|
*/
|
||||||
|
int SDF_ImportKey(Pointer hSessionHandle, byte[] pucKey, int puiKeyLength, PointerByReference phKeyHandle);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取私钥使用权限
|
||||||
|
*
|
||||||
|
* @param hSessionHandle 与设备建立的会话句柄
|
||||||
|
* @param uiKeyIndex 密码设备存储私钥的索引值
|
||||||
|
* @param pucPassword 使用私钥权限的标识码
|
||||||
|
* @param uiPwdLength 私钥访问控制码长度,不少于8字节
|
||||||
|
* @return 0 成功; 非0 失败,返回错误代码
|
||||||
|
*/
|
||||||
|
int SDF_GetPrivateKeyAccessRight(Pointer hSessionHandle, int uiKeyIndex, byte[] pucPassword, int uiPwdLength);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 导入会话密钥并用内部ECC私钥解密
|
* 导入会话密钥并用内部ECC私钥解密
|
||||||
*
|
*
|
||||||
|
@ -3,6 +3,11 @@ package com.sunyard.chsm.sdf.model;
|
|||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import lombok.NoArgsConstructor;
|
import lombok.NoArgsConstructor;
|
||||||
|
import org.springframework.util.Assert;
|
||||||
|
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
import java.nio.ByteOrder;
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author liulu
|
* @author liulu
|
||||||
@ -41,4 +46,40 @@ public class EccCipher {
|
|||||||
return rawData;
|
return rawData;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public byte[] toSdfData() {
|
||||||
|
byte[] d = new byte[164 + L];
|
||||||
|
byte[] l = ByteBuffer.allocate(4).order(ByteOrder.LITTLE_ENDIAN).putInt(L).array();
|
||||||
|
System.arraycopy(x, 0, d, 32, 32);
|
||||||
|
System.arraycopy(y, 0, d, 96, 32);
|
||||||
|
System.arraycopy(M, 0, d, 128, 32);
|
||||||
|
System.arraycopy(l, 0, d, 160, 4);
|
||||||
|
System.arraycopy(C, 0, d, 164, L);
|
||||||
|
return d;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static EccCipher fromBytes(byte[] cipher) {
|
||||||
|
Assert.notNull(cipher, "Ecc密文数据不能为null");
|
||||||
|
if (cipher[0] == 0x04) {
|
||||||
|
cipher = Arrays.copyOfRange(cipher, 1, cipher.length);
|
||||||
|
}
|
||||||
|
Assert.isTrue(cipher.length > 96, "Ecc加密数据格式错误");
|
||||||
|
if (cipher.length > 164
|
||||||
|
&& Arrays.equals(Arrays.copyOf(cipher, 32), new byte[32])
|
||||||
|
&& Arrays.equals(Arrays.copyOfRange(cipher, 64, 96), new byte[32])) {
|
||||||
|
int L = cipher.length - 164;
|
||||||
|
byte[] x = Arrays.copyOfRange(cipher, 32, 64);
|
||||||
|
byte[] y = Arrays.copyOfRange(cipher, 96, 128);
|
||||||
|
byte[] m = Arrays.copyOfRange(cipher, 128, 160);
|
||||||
|
byte[] c = Arrays.copyOfRange(cipher, 164, cipher.length);
|
||||||
|
return new EccCipher(x, y, m, L, c);
|
||||||
|
}
|
||||||
|
|
||||||
|
int L = cipher.length - 96;
|
||||||
|
byte[] x = Arrays.copyOfRange(cipher, 0, 32);
|
||||||
|
byte[] y = Arrays.copyOfRange(cipher, 32, 64);
|
||||||
|
byte[] m = Arrays.copyOfRange(cipher, 64, 96);
|
||||||
|
byte[] c = Arrays.copyOfRange(cipher, 96, cipher.length);
|
||||||
|
return new EccCipher(x, y, m, L, c);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,12 @@ package com.sunyard.chsm.sdf.model;
|
|||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import lombok.NoArgsConstructor;
|
import lombok.NoArgsConstructor;
|
||||||
|
import org.bouncycastle.util.encoders.Hex;
|
||||||
|
import org.springframework.util.Assert;
|
||||||
|
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author liulu
|
* @author liulu
|
||||||
@ -20,6 +26,9 @@ public class EccPubKey {
|
|||||||
// 公 钥 y 坐 标
|
// 公 钥 y 坐 标
|
||||||
private byte[] y;
|
private byte[] y;
|
||||||
|
|
||||||
|
public String getPubKeyHex() {
|
||||||
|
return Hex.toHexString(getPubKeyBytes());
|
||||||
|
}
|
||||||
|
|
||||||
public byte[] getPubKeyBytes() {
|
public byte[] getPubKeyBytes() {
|
||||||
byte[] rawKey = new byte[x.length + y.length];
|
byte[] rawKey = new byte[x.length + y.length];
|
||||||
@ -28,4 +37,43 @@ public class EccPubKey {
|
|||||||
return rawKey;
|
return rawKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public byte[] toSdfData() {
|
||||||
|
byte[] sdf = new byte[132];
|
||||||
|
System.arraycopy(Hex.decode("00010000"), 0, sdf, 0, 4);
|
||||||
|
System.arraycopy(x, 0, sdf, 36, 32);
|
||||||
|
System.arraycopy(y, 0, sdf, 100, 32);
|
||||||
|
return sdf;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static EccPubKey fromHex(String pubKeyHex) {
|
||||||
|
return fromBytes(Hex.decode(pubKeyHex));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static EccPubKey fromBytes(byte[] pubKey) {
|
||||||
|
Assert.notNull(pubKey, "公钥数据不能为null");
|
||||||
|
if (Objects.equals(pubKey.length, 65)) {
|
||||||
|
Assert.isTrue(Objects.equals(pubKey[0], 0x04), "Ecc公钥数据格式错误,必须04开头");
|
||||||
|
pubKey = Arrays.copyOfRange(pubKey, 1, pubKey.length);
|
||||||
|
} else if (Objects.equals(pubKey.length, 132)) {
|
||||||
|
// 00010000
|
||||||
|
byte[] bytes = Arrays.copyOf(pubKey, 4);
|
||||||
|
System.out.println(Hex.toHexString(bytes));
|
||||||
|
int anInt = ByteBuffer.wrap(bytes).getInt();
|
||||||
|
System.out.println(anInt);
|
||||||
|
|
||||||
|
pubKey = Arrays.copyOfRange(pubKey, 4, pubKey.length);
|
||||||
|
}
|
||||||
|
Assert.isTrue(Objects.equals(pubKey.length, 64) || Objects.equals(pubKey.length, 128), "Ecc公钥数据格式错误");
|
||||||
|
byte[] x = new byte[32];
|
||||||
|
byte[] y = new byte[32];
|
||||||
|
if (Objects.equals(pubKey.length, 64)) {
|
||||||
|
System.arraycopy(pubKey, 0, x, 0, 32);
|
||||||
|
System.arraycopy(pubKey, 32, y, 0, 32);
|
||||||
|
} else if (Objects.equals(pubKey.length, 128)) {
|
||||||
|
System.arraycopy(pubKey, 32, x, 0, 32);
|
||||||
|
System.arraycopy(pubKey, 96, y, 0, 32);
|
||||||
|
}
|
||||||
|
return new EccPubKey(256, x, y);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -10,6 +10,20 @@ import java.util.Arrays;
|
|||||||
*/
|
*/
|
||||||
public abstract class LangUtils {
|
public abstract class LangUtils {
|
||||||
|
|
||||||
|
|
||||||
|
public static byte[] removeLastZero(byte[] bytes) {
|
||||||
|
if (bytes == null) {
|
||||||
|
return bytes;
|
||||||
|
}
|
||||||
|
int len = bytes.length;
|
||||||
|
for (int i = len - 1; i >= 0; i--) {
|
||||||
|
if (bytes[i] != 0) {
|
||||||
|
return Arrays.copyOfRange(bytes, 0, i + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return bytes;
|
||||||
|
}
|
||||||
|
|
||||||
public static byte[] merge(byte[]... bytes) {
|
public static byte[] merge(byte[]... bytes) {
|
||||||
int newLen = Arrays.stream(bytes).mapToInt(it -> it.length).sum();
|
int newLen = Arrays.stream(bytes).mapToInt(it -> it.length).sum();
|
||||||
byte[] res = new byte[newLen];
|
byte[] res = new byte[newLen];
|
||||||
|
Loading…
Reference in New Issue
Block a user