Java调用UK动态库SKF接口(dll/so)——JNA的实现
Java调用UK动态库SKF接口(dll/so)——JNA的实现个人对Java语音了解有限,由于工作上的原因,写了一个的demo,仅供参考
情况:
[*]IntelliJ IDEA Community Edition 2024.1
[*]wiindows10
1-项目搭建
1.1-创建项目
1- 新建项目:选择Maven Archetype
a- Archetype:任意添加一个,默认第一个(org.apache.maven.archetypes:maven-archetype-archetype)
1.2-JNA依靠
在项目根目录下的pom.xml添加JNA依靠
<dependencies>
<!-- 添加JNA依赖 -->
<dependency>
<groupId>net.java.dev.jna</groupId>
<artifactId>jna</artifactId>
<version>5.10.0</version> <!-- 请检查并使用最新版本 -->
</dependency>
</dependencies>
1.3-目录创建
在src\mian下创建java目录,后续的代码文件将在这个目录下创建完成
2-Java SKFApi接口类的创建
涉及的内容:
[*]相关数据类型(各结构体):
[*]SKF接口
[*]算法ID
2.1-数据结构的定义
示例:
C的结构体定义:
typedef struct Struct_Version{
BYTE major;
BYTE minor;
}VERSION;
Java-JNA的对应的定义:
[*] getFieldOrder:必须存在的方法,里面的字符串跟结构体变量的顺序保持一致,没有会报错
[*] ByReference和ByValue:非必须的,在结构体类内部再定义两个静态类ByReference和ByValue 用于表示值传递还是引用传递,发起加上。
[*] 可增加其他方法:如果有需要对结构体完成某些操纵,可在后面增加方法,后面的部分结构体的部分中我会增加get和set方法,因为SKF接口中有涉及到将结构体转为byte*类型,或将byte*转为结构体的,以是增加get方法将结构体转为byte数组,set方法将byte数组转为结构体。
public static class VERSION extends Structure {
public int major;
public int minor;
// 定义值传递和指针传递类
public static class ByReference extends VERSION implements Structure.ByReference {
//指针和引用的传递使用ByReference
}
public static class ByValue extends VERSION implements Structure.ByValue {
//拷贝参数传递使用ByValue
}
@Override
protected List<String> getFieldOrder() {
return Arrays.asList(new String[]{
"major", "minor"});
}
}
2.2-SKF句柄相关
SKF涉及到的句柄有:设备句柄、应用句柄、容器句柄、会话密钥句柄、哈希句柄
C中的SKF相关的句柄:
DEVHANDLE *phDev = NULL; // 设备句柄
HAPPLICATION *phApplicatio = NULL; // 应用句柄
HCONTAINER *phContaine = NULL; // 容器句柄
HANDLE *phKeyHandle = NULL; // 会话密钥句柄
HANDLE *phHash = NULL; // 哈希句柄
Java-JNA的SKF相关的句柄:
// 句柄的定义
PointerByReference phDev = new PointerByReference();// 设备句柄
PointerByReference phApp = new PointerByReference();// 应用句柄
PointerByReference phContainer = new PointerByReference();// 容器句柄
PointerByReference sessionKey = new PointerByReference();// 会话密钥句柄
PointerByReference pHash = new PointerByReference(); // 哈希句柄
// 在获取句柄的时候传PointerByReference引用,在后续使用句柄的时候用getValue的值,以获取设备句柄,和使用设备句柄接口定义为例:连接设备、断开连接
long SKF_ConnectDev(String szName, PointerByReference phDev); // 连接设备
long SKF_DisConnectDev(Pointer hDev);//断开连接
// 示例
PointerByReference phDev = new PointerByReference();
SKF_ConnectDev(deviceName, phDev)
// 调用SKF_ConnectDev接口后,用getValue方法获取指针
Pointer hDev = phDev.getValue();
SKF_DisConnectDev(hDev)
2.3-注意事项
[*]SKF接口中定义为BOOL类型的参数,在Java-JNA中用int类型表示:1表示true,0表示false
[*]原因:如果用Java的Boolean类型传,可能会出现传true和false的效果一样
[*]大小端序问题:
[*]将数据以byte数组输出大概将byte数据输入(或转为结构体)时要注意此问题,SKF接口是小端序输出的。
2.4-SKFApi内容
请根据实际情况加载的动态库:
import com.sun.jna.*;
import com.sun.jna.ptr.ByteByReference;
import com.sun.jna.ptr.IntByReference;
import com.sun.jna.ptr.LongByReference;
import com.sun.jna.ptr.PointerByReference;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.Arrays;
import java.util.List;
public interface SkfApi extends Library {
SkfApi INSTANCE = Native.load("your_dll_name", SkfApi.class);
//设备操作
long SKF_EnumDev(int bPresent, ByteByReference szNameList, IntByReference pulSize);
long SKF_ConnectDev(String szName, PointerByReference phDev);
long SKF_DisConnectDev(Pointer hDev);
long SKF_GetDevInfo(Pointer hDev, DEVINFO pDevInfo);
//应用操作
int SKF_EnumApplication(Pointer hDev, ByteByReference szAppName, IntByReference pulSize);
int SKF_CreateApplication(Pointer hDev, String szAppName, String szAdminPin, int dwAdminPinRetryCount, String szUserPin, int dwUserPinRetryCount, int dwCreateFileRights, PointerByReference hApp);
int SKF_OpenApplication(Pointer hDev, String appName, PointerByReference hApp);
int SKF_CloseApplication(Pointer hApp);
//访问控制
int SKF_ChangeDevAuthKey(Pointer hDev, byte[] pbKeyValue, int ulKeyLen);
int SKF_DevAuth(Pointer hDev, byte[] pbAuthData, int ulLen);
int SKF_ChangePIN(Pointer hApplication, int ulPINType, String oldPIN, String newPIN, IntByReference pulRetryCount);
int SKF_GetPINInfo(Pointer hApplication, int ulPINType, IntByReference pulMaxRetryCount, IntByReference pulRemainRetryCount, IntByReference pbDefaultPin);
int SKF_VerifyPIN(Pointer hApplication, int ulPINType, String szPIN, IntByReference pulRetryCount);
int SKF_UnblockPIN(Pointer hApplication, String szAdminPIN, String szNewUserPIN, IntByReference pulRetryCount);
int SKF_ClearSecueState(Pointer hApplication);
//容器管理
int SKF_CreateContainer(Pointer hApplication, String szContainerName, PointerByReference phContainer);
int SKF_DeleteContainer(Pointer hApplication, String szContainerName);
int SKF_EnumContainer(Pointer hApplication, byte[] szContainerName, IntByReference pulSize);
int SKF_OpenContainer(Pointer hApplication, String szContainerName, PointerByReference phContainer);
int SKF_CloseContainer(Pointer hContainer);
int SKF_GetContainerType(Pointer hContainer, IntByReference pulContainerType);
// 密码服务
// int SKF_ExportCertificate(Pointer hContainer, boolean bSignFlag, byte[] pbCert, IntByReference pulCertLen);
// 接口中的boolean 都要改为int类型,1表示true,0表示false,如果是传boolean类型,不管是传true还是false,实际结果否是false的结果
int SKF_ExportCertificate(Pointer hContainer, int bSignFlag, byte[] pbCert, IntByReference pulCertLen);
//int SKF_ImportCertificate(Pointer hContainer, boolean bSignFlag, byte[] pbCert, IntByReference pulCertLen);
// 接口中的boolean 都要改为int类型,1表示true,0表示false,如果是传boolean类型,不管是传true还是false,实际结果否是false的结果
int SKF_ImportCertificate(Pointer hContainer, int bSignFlag, byte[] pbCert, IntByReference pulCertLen);
int SKF_EncryptInit(Pointer hKey, BLOCKCIPHERPARAM EncryptParam);
int SKF_Encrypt(Pointer hKey, byte[] pbData, int ulDataLen, byte[] pbEncryptedData, IntByReference pulEncryptedLen);
int SKF_EncryptUpdate(Pointer hKey, byte[] pbData, int ulDataLen, byte[] pbEncryptedData, IntByReference pulEncryptedLen);
int SKF_EncryptFinal(Pointer hKey, byte[] pbEncryptedData, IntByReference ulEncryptedDataLen);
int SKF_DecryptInit(Pointer hKey, BLOCKCIPHERPARAM DecryptParam);
int SKF_Decrypt(Pointer hKey, byte[] pbEncryptedData, int ulEncryptedLen, byte[] pbData, IntByReference pulDataLen);
int SKF_DecryptFinal(Pointer hKey, byte[] pbDecryptedData, IntByReference pulDecryptedDataLen);
//int SKF_ExportPublicKey(Pointer hContainer, boolean bSignFlag, byte[] pbBlob, IntByReference pulBlobLen);
// 接口中的boolean 都要改为int类型,1表示true,0表示false,如果是传boolean类型,不管是传true还是false,实际结果否是false的结果
int SKF_ExportPublicKey(Pointer hContainer, int bSignFlag, byte[] pbBlob, IntByReference pulBlobLen);
int SKF_GenECCKeyPair(Pointer hContainer, NativeLong ulAlgId, ECCPUBLICKEYBLOB pBlob);
int SKF_DigestInit(Pointer hDev, int ulAlgID, ECCPUBLICKEYBLOB pPubKey, byte[] pucID, int ulIDLen, PointerByReference phHash);
int SKF_Digest(Pointer hHash, byte[] pbData, int ulDataLen, byte[] pbHashData, IntByReference pulHashLen);
int SKF_DigestUpdate(Pointer hHash, byte[] pbData, int ulDataLen);
int SKF_DigestFinal(Pointer hHash, byte[] pHashData, IntByReference pulHashLen);
int SKF_RSASignData(Pointer hContainer,byte[] pbData, int ulDataLen,byte[]pbSignature,IntByReference pulSignLen);
int SKF_RSAVerify(Pointer hContainer,RSAPUBLICKEYBLOB pPubKey,byte[] pbData, int ulDataLen,byte[]pbSignature,int ulSignLen);
int SKF_ECCSignData(Pointer hContainer, byte[] pbData, int ulDataLen, ECCSIGNATUREBLOB pSignature);
int SKF_ECCVerify(Pointer hDev, ECCPUBLICKEYBLOB pECCPubKeyBlob, byte[] pbData, int ulDataLen, ECCSIGNATUREBLOB pSignature);
int SKF_RSAExportSessionKey(Pointer hContainer, int ulAlgId, RSAPUBLICKEYBLOB pPubKey, byte[] pData, IntByReference pulDataLen, PointerByReference phSessionKey);
int SKF_ECCExportSessionKey(Pointer hContainer, int ulAlgId, ECCPUBLICKEYBLOB pPubKey, ECCCIPHERBLOB pData, PointerByReference phSessionKey);
int SKF_ImportECCKeyPair(Pointer hContainer, ENVELOPEDKEYBLOB pEnvelopedKeyBlob);
int SKF_ExtECCSign(Pointer hDev, ECCPRIVATEKEYBLOB pECCPriKeyBlob, byte[] pbData, int ulDataLen, ECCSIGNATUREBLOB pSignature);
int SKF_ExtECCVerify(Pointer hDev, ECCPUBLICKEYBLOB pECCPubKeyBlob, byte[] pbData, int ulDataLen, ECCSIGNATUREBLOB pSignature);
int SKF_ExtECCEncrypt(Pointer hDev, ECCPUBLICKEYBLOB pECCPubKeyBlob, byte[] pbPlainText, int ulPlainTextLen, ECCCIPHERBLOB pCipherText);
int SKF_ExtECCDecrypt(Pointer hDev, ECCPRIVATEKEYBLOB pECCPriKeyBlob, ECCCIPHERBLOB pCipherText, byte[] pbPlainText, IntByReference pulPlainTextLen);
int SKF_ImportSessionKey(Pointer hCnt, int ulAlgId, byte[] pbWrapedData, int ulWrapedLen, PointerByReference hkey);
int SKF_SetSymmKey(Pointer hDev, byte[] pbKey, int ulAlgID, PointerByReference phKey);
int SKF_CloseHandle(Pointer hHandle);
public static class VERSION extends Structure {
public int major;
public int minor;
public static class ByReference extends VERSION implements Structure.ByReference {
}
public static class ByValue extends VERSION implements Structure.ByValue {
}
@Override
protected List<String> getFieldOrder() {
return Arrays.asList(new String[]{
"major", "minor"});
}
}
public static class DEVINFO extends Structure {
public VERSION Version;
public byte[] Manufacturer = new byte;
public byte[] Issuer = new byte;
public byte[] Label = new byte;
public byte[] SerialNumber = new byte;
public VERSION HWVersion;
public VERSION FirmwareVersion;
public int AlgSymCap;
public int AlgAsymCap;
public int AlgHashCap;
public int DevAuthAlgId;
public int TotalSpace;
public int FreeSpace;
public byte[] Reserved = new byte;
public static class ByReference extends DEVINFO implements Structure.ByReference {
}
public static class ByValue extends DEVINFO implements Structure.ByValue {
}
@Override
protected List<String> getFieldOrder() {
return Arrays.asList(new String[]{
"Version", "Manufacturer", "Issuer", "Label", "SerialNumber", "HWVersion", "FirmwareVersion", "AlgSymCap", "AlgAsymCap", "AlgHashCap", "DevAuthAlgId" , "TotalSpace", "FreeSpace", "Reserved"});
}
}
public static class BLOCKCIPHERPARAM extends Structure {
public byte[] IVS = new byte;
public int IVLen = 0;
public int PaddingType = 0;
public int FeedBitLen = 0;
@Override
protected List<String> getFieldOrder() {
return Arrays.asList(new String[]{
"IVS", "IVLen", "PaddingType", "FeedBitLen"});
}
public static class ByReference extends BLOCKCIPHERPARAM implements Structure.ByReference {
}
public static class ByValue extends BLOCKCIPHERPARAM implements Structure.ByValue {
}
public void setBlobCipherParam(byte[] IV, int ivLen, int PaddingType, int FeedBitLen){
this.IVS = IV;
this.IVLen = ivLen;
this.PaddingType = PaddingType;//填充方式,0表示不填充,1表示按照PKCS5方式进行填充。
this.FeedBitLen = FeedBitLen;
}
}
public static class ECCPUBLICKEYBLOB extends Structure {
public static final int ECC_MAX_XCOORDINATE_BITS_LEN = 512;
public static final int ECC_MAX_YCOORDINATE_BITS_LEN = 512;
public int BitLen;
public byte[] XCoordinate = new byte;
public byte[] YCoordinate = new byte;
@Override
protected List<String> getFieldOrder() {
return Arrays.asList(new String[]{
"BitLen", "XCoordinate", "YCoordinate"});
}
public static class ByReference extends ECCPUBLICKEYBLOB implements Structure.ByReference {
}
public static class ByValue extends ECCPUBLICKEYBLOB implements Structure.ByValue {
}
public byte[] getEccPublicBlob() {
byte[] eccPublicBlob = new byte;
int bitLenInt = this.BitLen;
byte[] bitLenBytes = new byte;
bitLenBytes = (byte) (bitLenInt & 0xFF); // 最低有效字节
bitLenBytes = (byte) ((bitLenInt >> 8) & 0xFF);
bitLenBytes = (byte) ((bitLenInt >> 16)
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页:
[1]