sdf
This commit is contained in:
parent
1cf14e0884
commit
0acb061756
@ -49,6 +49,11 @@
|
|||||||
<groupId>net.java.dev.jna</groupId>
|
<groupId>net.java.dev.jna</groupId>
|
||||||
<artifactId>jna</artifactId>
|
<artifactId>jna</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.google.guava</groupId>
|
||||||
|
<artifactId>guava</artifactId>
|
||||||
|
<version>33.2.1-jre</version>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
|
|
||||||
|
@ -6,9 +6,12 @@ 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.EccKey;
|
import com.sunyard.chsm.sdf.model.EccKey;
|
||||||
import com.sunyard.chsm.sdf.model.EccPubKey;
|
import com.sunyard.chsm.sdf.model.EccPubKey;
|
||||||
|
import com.sunyard.chsm.sdf.model.SDF_DeviceInfo;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
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;
|
||||||
@ -17,6 +20,7 @@ import java.util.concurrent.ConcurrentHashMap;
|
|||||||
* @author liulu
|
* @author liulu
|
||||||
* @since 2024/11/4
|
* @since 2024/11/4
|
||||||
*/
|
*/
|
||||||
|
@Slf4j
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
public abstract class JnaSdfAdaptor implements SdfApiAdapter {
|
public abstract class JnaSdfAdaptor implements SdfApiAdapter {
|
||||||
|
|
||||||
@ -87,7 +91,21 @@ public abstract class JnaSdfAdaptor implements SdfApiAdapter {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public DeviceInfo getDeviceInfo(String sessionHandle) {
|
public DeviceInfo getDeviceInfo(String sessionHandle) {
|
||||||
return null;
|
|
||||||
|
SDF_DeviceInfo sdfInfo = new SDF_DeviceInfo();
|
||||||
|
sdfLibrary.SDF_GetDeviceInfo(getSessionHandle(sessionHandle), sdfInfo);
|
||||||
|
|
||||||
|
DeviceInfo deviceInfo = new DeviceInfo();
|
||||||
|
deviceInfo.setIssuerName(new String(sdfInfo.IssuerName));
|
||||||
|
deviceInfo.setDeviceName(new String(sdfInfo.DeviceName));
|
||||||
|
deviceInfo.setDeviceSerial(new String(sdfInfo.DeviceSerial));
|
||||||
|
deviceInfo.setDeviceVersion(sdfInfo.DeviceVersion);
|
||||||
|
deviceInfo.setStandardVersion(sdfInfo.StandardVersion);
|
||||||
|
deviceInfo.setAsymAlgAbility(sdfInfo.AsymAlgAbility);
|
||||||
|
deviceInfo.setSymAlgAbility(sdfInfo.SymAlgAbility);
|
||||||
|
deviceInfo.setHashAlgAbility(sdfInfo.HashAlgAbility);
|
||||||
|
deviceInfo.setBufferSize(sdfInfo.BufferSize);
|
||||||
|
return deviceInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -100,7 +118,10 @@ public abstract class JnaSdfAdaptor implements SdfApiAdapter {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public EccPubKey exportEncPublicKeyECC(String sessionHandle, int uiKeyIndex) {
|
public EccPubKey exportEncPublicKeyECC(String sessionHandle, int uiKeyIndex) {
|
||||||
return null;
|
byte[] pubKey = new byte[132];
|
||||||
|
Pointer hSessionHandle = getSessionHandle(sessionHandle);
|
||||||
|
sdfLibrary.SDF_ExportEncPublicKey_ECC(hSessionHandle, uiKeyIndex, pubKey);
|
||||||
|
return new EccPubKey(256, Arrays.copyOfRange(pubKey, 36, 68), Arrays.copyOfRange(pubKey, 100, 132));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -27,7 +27,7 @@ public class SdfApiAdapterFactory {
|
|||||||
case enc001:
|
case enc001:
|
||||||
return new SunyardJnaSdfAdaptor(device.getServiceIp(), device.getServicePort());
|
return new SunyardJnaSdfAdaptor(device.getServiceIp(), device.getServicePort());
|
||||||
default:
|
default:
|
||||||
return null;
|
throw new UnsupportedOperationException("不支持的设备型号: " + device.getManufacturerModel());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -24,7 +24,7 @@ public class SunyardJnaSdfAdaptor extends JnaSdfAdaptor {
|
|||||||
private final Integer dealTimeout;
|
private final Integer dealTimeout;
|
||||||
|
|
||||||
public SunyardJnaSdfAdaptor(String ip, int port) {
|
public SunyardJnaSdfAdaptor(String ip, int port) {
|
||||||
this(ip, port, "libsdf");
|
this(ip, port, "sdf");
|
||||||
}
|
}
|
||||||
|
|
||||||
public SunyardJnaSdfAdaptor(String ip, int port, String libName) {
|
public SunyardJnaSdfAdaptor(String ip, int port, String libName) {
|
||||||
|
@ -2,7 +2,9 @@ package com.sunyard.chsm.sdf.lib;
|
|||||||
|
|
||||||
import com.sun.jna.Library;
|
import com.sun.jna.Library;
|
||||||
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.model.SDF_DeviceInfo;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author liulu
|
* @author liulu
|
||||||
@ -50,7 +52,7 @@ public interface SdfLibrary extends Library {
|
|||||||
* @param pstDeviceInfo 设备能力描述信息,内容及格式见设备信息定义
|
* @param pstDeviceInfo 设备能力描述信息,内容及格式见设备信息定义
|
||||||
* @return 0 成功; 非0 失败,返回错误代码
|
* @return 0 成功; 非0 失败,返回错误代码
|
||||||
*/
|
*/
|
||||||
int SDF_GetDeviceInfo(Pointer hSessionHandle, byte[] pstDeviceInfo);
|
int SDF_GetDeviceInfo(Pointer hSessionHandle, SDF_DeviceInfo pstDeviceInfo);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 产生随机数
|
* 产生随机数
|
||||||
@ -63,4 +65,237 @@ public interface SdfLibrary extends Library {
|
|||||||
int SDF_GenerateRandom(Pointer hSessionHandle, int uiLength, byte[] pucRandom);
|
int SDF_GenerateRandom(Pointer hSessionHandle, int uiLength, byte[] pucRandom);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 生成ECC密钥对
|
||||||
|
*
|
||||||
|
* @param phSessionHandle 会话句柄
|
||||||
|
* @param uiAlgID 算法标识
|
||||||
|
* @param uiKeyBits 密钥长度
|
||||||
|
* @param pucPublicKey 输出的ECC公钥结构
|
||||||
|
* @param pucPrivateKey 输出的ECC私钥结构
|
||||||
|
* @return int 响应码
|
||||||
|
*/
|
||||||
|
int SDF_GenerateKeyPair_ECC(
|
||||||
|
Pointer phSessionHandle,
|
||||||
|
int uiAlgID,
|
||||||
|
int uiKeyBits,
|
||||||
|
byte[] pucPublicKey,
|
||||||
|
byte[] pucPrivateKey
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 导出签名公钥
|
||||||
|
*
|
||||||
|
* @param phSessionHandle
|
||||||
|
* @param uiKeyIndex
|
||||||
|
* @param pucPublicKey
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
int SDF_ExportSignPublicKey_ECC(Pointer phSessionHandle,
|
||||||
|
int uiKeyIndex,
|
||||||
|
byte[] pucPublicKey);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 导出加密公钥
|
||||||
|
*
|
||||||
|
* @param phSessionHandle
|
||||||
|
* @param uiKeyIndex
|
||||||
|
* @param pucPublicKey
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
int SDF_ExportEncPublicKey_ECC(Pointer phSessionHandle,
|
||||||
|
int uiKeyIndex,
|
||||||
|
byte[] pucPublicKey);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 密钥加密
|
||||||
|
*
|
||||||
|
* @param phSessionHandle 会话句柄
|
||||||
|
* @param uiAlgID 算法标识
|
||||||
|
* @param pucPublicKey ECC公钥结构
|
||||||
|
* @param pucData 输入的数据明文
|
||||||
|
* @param pucDatalength 输入的数据明文长度
|
||||||
|
* @param pucEncData 输出的密文数据
|
||||||
|
* @return int 响应码
|
||||||
|
*/
|
||||||
|
int SDF_ExternalEncrypt_ECC(Pointer phSessionHandle, int uiAlgID, byte[] pucPublicKey, byte[] pucData, int pucDatalength, byte[] pucEncData);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 密钥解密
|
||||||
|
*
|
||||||
|
* @param phSessionHandle 会话句柄
|
||||||
|
* @param uiAlgID 算法标识
|
||||||
|
* @param pucPrivateKey ECC私钥结构
|
||||||
|
* @param pucEncData 输入的密文数据
|
||||||
|
* @param pucDataOut 输出的数据明文
|
||||||
|
* @param pucDatalength 输出的数据明文长度
|
||||||
|
* @return int 响应码
|
||||||
|
*/
|
||||||
|
int SDF_ExternalDecrypt_ECC(Pointer phSessionHandle, int uiAlgID, byte[] pucPrivateKey, byte[] pucEncData, byte[] pucDataOut, IntByReference pucDatalength);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 外部ECC签名
|
||||||
|
*
|
||||||
|
* @param phSessionHandle 会话句柄
|
||||||
|
* @param uiAlgID 算法标识
|
||||||
|
* @param pucPublicKey ECC公钥结构
|
||||||
|
* @param pucData 输入的数据明文
|
||||||
|
* @param pucDataLength 输入的数据明文长度
|
||||||
|
* @param pucECCSignature 输出的签名值数据
|
||||||
|
* @return int 响应码
|
||||||
|
*/
|
||||||
|
int SDF_ExternalSign_ECC(
|
||||||
|
Pointer phSessionHandle,
|
||||||
|
int uiAlgID,
|
||||||
|
byte[] pucPublicKey,
|
||||||
|
byte[] pucData,
|
||||||
|
int pucDataLength,
|
||||||
|
byte[] pucECCSignature
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 外部ECC验签
|
||||||
|
*
|
||||||
|
* @param phSessionHandle 会话句柄
|
||||||
|
* @param uiAlgID 算法标识
|
||||||
|
* @param pucPublicKey ECC公钥结构
|
||||||
|
* @param pucData 输入的数据明文
|
||||||
|
* @param pucDataLength 输入的数据明文长度
|
||||||
|
* @param pucECCSignature 输入的签名值数据
|
||||||
|
* @return int 响应码
|
||||||
|
*/
|
||||||
|
int SDF_ExternalVerify_ECC(Pointer phSessionHandle, int uiAlgID, byte[] pucPublicKey, byte[] pucData, int pucDataLength, byte[] pucECCSignature);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 基于ECC算法的数字信封转换
|
||||||
|
*
|
||||||
|
* @param hSessionHandle 与设备建立的会话句柄
|
||||||
|
* @param uiKeyIndex 密码设备内部存储ECC密钥对索引值
|
||||||
|
* @param uiAlgID 外部ECC公钥的算法标识 SGD_SM2_1
|
||||||
|
* @param pucPublicKey 外部ECC公钥结构
|
||||||
|
* @param pucEncDateIn 缓冲区指针,用于存放输入的会话密钥密文
|
||||||
|
* @param pucEncDateOut 缓冲区指针,用于存放输出的会话密钥密文
|
||||||
|
* @return 0 成功; 非0 失败,返回错误代码
|
||||||
|
*/
|
||||||
|
int SDF_ExchangeDigitEnvelopeBaseOnECC(Pointer hSessionHandle, int uiKeyIndex, int uiAlgID, byte[] pucPublicKey, byte[] pucEncDateIn, byte[] pucEncDateOut);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 导入会话密钥并用内部ECC私钥解密
|
||||||
|
*
|
||||||
|
* @param phSessionHandle
|
||||||
|
* @param uiISKIndex
|
||||||
|
* @param puckey
|
||||||
|
* @param phKeyhandle
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
int SDF_ImportKeyWithISK_ECC(Pointer phSessionHandle,
|
||||||
|
int uiISKIndex,
|
||||||
|
byte[] puckey,
|
||||||
|
PointerByReference phKeyhandle);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 销毁会话密钥
|
||||||
|
*
|
||||||
|
* @param phSessionHandle
|
||||||
|
* @param phKeyhandle
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
int SDF_DestroyKey(Pointer phSessionHandle, PointerByReference phKeyhandle);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 对称加密
|
||||||
|
*
|
||||||
|
* @param phSessionHandle 会话句柄
|
||||||
|
* @param hKeyHandle 密钥句柄
|
||||||
|
* @param uiAlgID 算法标识
|
||||||
|
* @param pucIV IV数据
|
||||||
|
* @param pucData 待加密数据
|
||||||
|
* @param pucDataLength 待加密数据长度
|
||||||
|
* @param pucEncData 存放密文容器
|
||||||
|
* @param pucEncDataLength 密文长度
|
||||||
|
* @return int 响应码
|
||||||
|
*/
|
||||||
|
int SDF_Encrypt(
|
||||||
|
Pointer phSessionHandle,
|
||||||
|
Pointer hKeyHandle,
|
||||||
|
int uiAlgID,
|
||||||
|
byte[] pucIV,
|
||||||
|
byte[] pucData,
|
||||||
|
int pucDataLength,
|
||||||
|
byte[] pucEncData,
|
||||||
|
IntByReference pucEncDataLength
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 对称解密
|
||||||
|
*
|
||||||
|
* @param phSessionHandle 会话句柄
|
||||||
|
* @param hKeyHandle 密钥句柄
|
||||||
|
* @param uiAlgID 算法标识
|
||||||
|
* @param pucIV IV数据
|
||||||
|
* @param purEncData 指向密文数据的指针
|
||||||
|
* @param encDataLength 密文数据长度
|
||||||
|
* @param pucData 输出明文数据
|
||||||
|
* @param pucDataLength 输出明文数据长度
|
||||||
|
* @return int 响应码
|
||||||
|
*/
|
||||||
|
int SDF_Decrypt(
|
||||||
|
Pointer phSessionHandle,
|
||||||
|
Pointer hKeyHandle,
|
||||||
|
int uiAlgID,
|
||||||
|
byte[] pucIV,
|
||||||
|
byte[] purEncData,
|
||||||
|
int encDataLength,
|
||||||
|
byte[] pucData,
|
||||||
|
IntByReference pucDataLength
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 杂凑运算初始化
|
||||||
|
*
|
||||||
|
* @param phSessionHandle 会话句柄
|
||||||
|
* @param uiAlgID 算法标识
|
||||||
|
* @param pucPublicKey ECC公钥结构
|
||||||
|
* @param pucID 签名者的ID值
|
||||||
|
* @param pucIDlength 签名者ID的长度
|
||||||
|
* @return int 响应码
|
||||||
|
*/
|
||||||
|
int SDF_HashInit(Pointer phSessionHandle, int uiAlgID, byte[] pucPublicKey, String pucID, int pucIDlength);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 多包杂凑运算
|
||||||
|
*
|
||||||
|
* @param phSessionHandle 会话句柄
|
||||||
|
* @param pucData 输入的数据明文
|
||||||
|
* @param uiDataLength 输入的数据明文长度
|
||||||
|
* @return int 响应码
|
||||||
|
*/
|
||||||
|
int SDF_HashUpdate(
|
||||||
|
Pointer phSessionHandle, // 使用IntByReference,因为SessionHandle可能是引用类型的
|
||||||
|
byte[] pucData, // 输入的明文数据作为字节数组
|
||||||
|
int uiDataLength // 明文数据长度
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 杂凑运算结束
|
||||||
|
*
|
||||||
|
* @param phSessionHandle 会话句柄
|
||||||
|
* @param pucHash 杂凑结果
|
||||||
|
* @param pucHashLength 杂凑结果长度
|
||||||
|
* @return int 响应码
|
||||||
|
*/
|
||||||
|
int SDF_HashFinal(Pointer phSessionHandle, byte[] pucHash, IntByReference pucHashLength);
|
||||||
|
|
||||||
|
|
||||||
|
int SDF_CalculateMAC(Pointer phSessionHandle,
|
||||||
|
Pointer hKeyHadnle,
|
||||||
|
int uiAlgID,
|
||||||
|
byte[] pucIV,
|
||||||
|
byte[] purData,
|
||||||
|
int pucDatalength,
|
||||||
|
byte[] pucMAC,
|
||||||
|
IntByReference pucMACLength);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
40
chsm-common/src/main/java/com/sunyard/chsm/sdf/model/SDF_DeviceInfo.java
Executable file
40
chsm-common/src/main/java/com/sunyard/chsm/sdf/model/SDF_DeviceInfo.java
Executable file
@ -0,0 +1,40 @@
|
|||||||
|
package com.sunyard.chsm.sdf.model;
|
||||||
|
|
||||||
|
import com.sun.jna.Structure;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author liulu
|
||||||
|
* @version V1.0
|
||||||
|
* @since 2022/10/11
|
||||||
|
*/
|
||||||
|
@Structure.FieldOrder({"IssuerName", "DeviceName", "DeviceSerial", "DeviceVersion", "StandardVersion", "AsymAlgAbility", "SymAlgAbility", "HashAlgAbility", "BufferSize"})
|
||||||
|
public class SDF_DeviceInfo extends Structure {
|
||||||
|
|
||||||
|
// 设备 生产 厂商名称
|
||||||
|
public byte[] IssuerName = new byte[40];
|
||||||
|
|
||||||
|
// 设备 型号
|
||||||
|
public byte[] DeviceName = new byte[16];
|
||||||
|
|
||||||
|
// 设 备 编 号 ,包 含 :日 期 (8 字 符 )、批 次 号 (3 字 符 )、流 水 号 (5 字 符 )
|
||||||
|
public byte[] DeviceSerial = new byte[16];
|
||||||
|
|
||||||
|
// 密码 设备 内部软件的版本号
|
||||||
|
public int DeviceVersion;
|
||||||
|
|
||||||
|
// 密码 设备 支持的接口规范版本号
|
||||||
|
public int StandardVersion;
|
||||||
|
|
||||||
|
// 前4字节表示支持的算法,表示方法为非对称算法标识 按位或的结果;后4字节表示算法的最大模长,表示方法 为支持的模长按位或的结果
|
||||||
|
public int[] AsymAlgAbility = new int[2];
|
||||||
|
|
||||||
|
// 所有支持的对称算法,表示方法为对称算法标识按位或 运算结果
|
||||||
|
public int SymAlgAbility;
|
||||||
|
|
||||||
|
// 所有支持的杂凑算法,表示方法为杂凑算法标识按位或 运算结果
|
||||||
|
public int HashAlgAbility;
|
||||||
|
|
||||||
|
// 支持 的最 大文件存储空间(单位字节)
|
||||||
|
public int BufferSize;
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,59 @@
|
|||||||
|
package com.sunyard.chsm.sdf.util;
|
||||||
|
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author liulu
|
||||||
|
* @version V1.0
|
||||||
|
* @since 2024/11/06
|
||||||
|
*/
|
||||||
|
public abstract class LangUtils {
|
||||||
|
|
||||||
|
public static byte[] merge(byte[]... bytes) {
|
||||||
|
int newLen = Arrays.stream(bytes).mapToInt(it -> it.length).sum();
|
||||||
|
byte[] res = new byte[newLen];
|
||||||
|
|
||||||
|
int mergedLen = 0;
|
||||||
|
for (byte[] item : bytes) {
|
||||||
|
System.arraycopy(item, 0, res, mergedLen, item.length);
|
||||||
|
mergedLen += item.length;
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static byte[] toByteArray(int i) {
|
||||||
|
byte[] result = new byte[4];
|
||||||
|
result[0] = (byte) ((i >> 24) & 0xFF);
|
||||||
|
result[1] = (byte) ((i >> 16) & 0xFF);
|
||||||
|
result[2] = (byte) ((i >> 8) & 0xFF);
|
||||||
|
result[3] = (byte) (i & 0xFF);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static byte[] toByteArray(long i) {
|
||||||
|
ByteBuffer buffer = ByteBuffer.allocate(Long.BYTES);
|
||||||
|
buffer.putLong(i);
|
||||||
|
return buffer.array();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int toInt(byte[] bytes) {
|
||||||
|
if (bytes == null || bytes.length != Integer.BYTES) {
|
||||||
|
throw new IllegalArgumentException("转int需要4个字节");
|
||||||
|
}
|
||||||
|
int result = 0;
|
||||||
|
for (int i = 0; i < 4; i++) {
|
||||||
|
int shift = (3 - i) * 8;
|
||||||
|
result += (bytes[i] & 0xFF) << shift;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static long toLong(byte[] bytes) {
|
||||||
|
if (bytes == null || bytes.length != Long.BYTES) {
|
||||||
|
throw new IllegalArgumentException("转long需要8个字节");
|
||||||
|
}
|
||||||
|
ByteBuffer buffer = ByteBuffer.wrap(bytes);
|
||||||
|
return buffer.getLong();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,65 @@
|
|||||||
|
package com.sunyard.chsm.sdf.util;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author liulu
|
||||||
|
*/
|
||||||
|
public abstract class PaddingUtil {
|
||||||
|
|
||||||
|
public static byte[] PKCS7Padding(byte[] content, int blockSize) {
|
||||||
|
if (content == null || blockSize < 8)
|
||||||
|
throw new IllegalStateException("parameter error");
|
||||||
|
|
||||||
|
int len = content.length;
|
||||||
|
int remain = len % blockSize;
|
||||||
|
int NUM = blockSize - remain;
|
||||||
|
|
||||||
|
int Len = blockSize * (len / blockSize + 1);
|
||||||
|
byte[] padded = new byte[Len];
|
||||||
|
System.arraycopy(content, 0, padded, 0, len);
|
||||||
|
for (int i = 0; i < NUM; i++)
|
||||||
|
padded[len + i] = (byte) NUM;
|
||||||
|
|
||||||
|
return padded;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static byte[] PKCS7Padding(byte[] content) {
|
||||||
|
try {
|
||||||
|
return PKCS7Padding(content, 16);
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static byte[] PKCS5Padding(byte[] content) throws Exception {
|
||||||
|
return PKCS7Padding(content, 8);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static byte[] PKCS7Unpadding(byte[] content, int blockSize)
|
||||||
|
throws Exception {
|
||||||
|
if (blockSize < 8 || content == null || content.length % blockSize != 0)
|
||||||
|
throw new Exception("parameter error");
|
||||||
|
return PKCS7Unpadding(content);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static byte[] PKCS7Unpadding(byte[] content) {
|
||||||
|
if (content == null || content.length < 8)
|
||||||
|
throw new IllegalStateException("parameter error");
|
||||||
|
|
||||||
|
int len = content.length;
|
||||||
|
int NUM = content[len - 1];
|
||||||
|
if (NUM > len)
|
||||||
|
throw new IllegalStateException("invalid padding");
|
||||||
|
for (int i = 0; i < NUM; i++)
|
||||||
|
if (content[len - i - 1] != NUM)
|
||||||
|
throw new IllegalStateException("invalid padding");
|
||||||
|
byte[] unpadded = new byte[len - NUM];
|
||||||
|
System.arraycopy(content, 0, unpadded, 0, len - NUM);
|
||||||
|
return unpadded;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static byte[] PKCS5Unpadding(byte[] content) throws Exception {
|
||||||
|
return PKCS7Unpadding(content, 8);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
BIN
chsm-common/src/main/resources/linux-aarch64/libsdf.so
Normal file
BIN
chsm-common/src/main/resources/linux-aarch64/libsdf.so
Normal file
Binary file not shown.
BIN
chsm-common/src/main/resources/linux-x86-64/libsdf.so
Normal file
BIN
chsm-common/src/main/resources/linux-x86-64/libsdf.so
Normal file
Binary file not shown.
BIN
chsm-common/src/main/resources/win32-x86-64/libsdf.dll
Normal file
BIN
chsm-common/src/main/resources/win32-x86-64/libsdf.dll
Normal file
Binary file not shown.
@ -117,10 +117,19 @@
|
|||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
|
<resources>
|
||||||
|
<resource>
|
||||||
|
<directory>src/main/resources</directory>
|
||||||
|
<includes>
|
||||||
|
<include>**/**</include>
|
||||||
|
</includes>
|
||||||
|
<filtering>false</filtering>
|
||||||
|
</resource>
|
||||||
|
</resources>
|
||||||
|
|
||||||
<plugins>
|
<plugins>
|
||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
@ -4,6 +4,13 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
|||||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
import com.sunyard.chsm.mapper.SpDeviceMapper;
|
import com.sunyard.chsm.mapper.SpDeviceMapper;
|
||||||
import com.sunyard.chsm.model.entity.Device;
|
import com.sunyard.chsm.model.entity.Device;
|
||||||
|
import com.sunyard.chsm.sdf.adapter.SdfApiAdapter;
|
||||||
|
import com.sunyard.chsm.sdf.adapter.SdfApiAdapterFactory;
|
||||||
|
import com.sunyard.chsm.sdf.context.DeviceContext;
|
||||||
|
import com.sunyard.chsm.sdf.model.DeviceInfo;
|
||||||
|
import com.sunyard.chsm.sdf.model.EccPubKey;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.bouncycastle.util.encoders.Hex;
|
||||||
import org.springframework.beans.factory.InitializingBean;
|
import org.springframework.beans.factory.InitializingBean;
|
||||||
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
|
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
|
||||||
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
|
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
|
||||||
@ -12,12 +19,14 @@ import org.springframework.util.CollectionUtils;
|
|||||||
|
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
import java.time.Duration;
|
import java.time.Duration;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author liulu
|
* @author liulu
|
||||||
* @since 2024/11/4
|
* @since 2024/11/4
|
||||||
*/
|
*/
|
||||||
|
@Slf4j
|
||||||
@Component
|
@Component
|
||||||
public class DeviceTask implements InitializingBean {
|
public class DeviceTask implements InitializingBean {
|
||||||
|
|
||||||
@ -34,7 +43,7 @@ public class DeviceTask implements InitializingBean {
|
|||||||
|
|
||||||
for (int i = 1; i < 500; i++) {
|
for (int i = 1; i < 500; i++) {
|
||||||
Page<Device> devicePage = spDeviceMapper.selectPage(
|
Page<Device> devicePage = spDeviceMapper.selectPage(
|
||||||
new Page<>(i, 100L),
|
new Page<>(i, 20L),
|
||||||
new LambdaQueryWrapper<Device>().orderByAsc(Device::getId)
|
new LambdaQueryWrapper<Device>().orderByAsc(Device::getId)
|
||||||
);
|
);
|
||||||
List<Device> records = devicePage.getRecords();
|
List<Device> records = devicePage.getRecords();
|
||||||
@ -43,15 +52,38 @@ public class DeviceTask implements InitializingBean {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (Device record : records) {
|
for (Device record : records) {
|
||||||
|
DeviceContext context = new DeviceContext();
|
||||||
|
context.setServiceIp(record.getServiceIp());
|
||||||
|
context.setServicePort(record.getServicePort());
|
||||||
|
context.setManufacturer(record.getManufacturer());
|
||||||
|
context.setManufacturerModel(record.getManufacturerModel());
|
||||||
|
boolean connected = false;
|
||||||
|
try {
|
||||||
|
SdfApiAdapter sdfApiAdapter = SdfApiAdapterFactory.newInstance(context);
|
||||||
|
String dh = sdfApiAdapter.openDevice();
|
||||||
|
String sh = sdfApiAdapter.openSession(dh);
|
||||||
|
DeviceInfo info = sdfApiAdapter.getDeviceInfo(sh);
|
||||||
|
log.info("get DeviceInfo: {}", info);
|
||||||
|
EccPubKey eccPubKey = sdfApiAdapter.exportEncPublicKeyECC(sh, 2);
|
||||||
|
log.info("exportEncPublicKeyECC: {}", Hex.toHexString(eccPubKey.getPubKeyBytes()));
|
||||||
|
sdfApiAdapter.closeSession(sh);
|
||||||
|
sdfApiAdapter.closeDevice(dh);
|
||||||
|
connected = true;
|
||||||
|
|
||||||
|
} catch (Exception ex) {
|
||||||
|
log.warn("设备 {}:{} 连接异常", record.getServiceIp(), record.getServicePort(), ex);
|
||||||
|
}
|
||||||
|
Device up = new Device();
|
||||||
|
up.setId(record.getId());
|
||||||
|
up.setConnected(connected);
|
||||||
|
LocalDateTime now = LocalDateTime.now();
|
||||||
|
if (connected) {
|
||||||
|
up.setLastConnectedTime(now);
|
||||||
|
}
|
||||||
|
up.setLastCheckTime(now);
|
||||||
|
spDeviceMapper.updateById(up);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
Loading…
Reference in New Issue
Block a user