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接口类的创建
涉及的内容:
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[64];
- public byte[] Issuer = new byte[64];
- public byte[] Label = new byte[32];
- public byte[] SerialNumber = new byte[32];
- 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[64];
- 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[32];
- 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[ECC_MAX_XCOORDINATE_BITS_LEN / 8];
- public byte[] YCoordinate = new byte[ECC_MAX_YCOORDINATE_BITS_LEN / 8];
- @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[132];
- int bitLenInt = this.BitLen;
- byte[] bitLenBytes = new byte[3];
- bitLenBytes[2] = (byte) (bitLenInt & 0xFF); // 最低有效字节
- bitLenBytes[1] = (byte) ((bitLenInt >> 8) & 0xFF);
- bitLenBytes[0] = (byte) ((bitLenInt >> 16)
复制代码 免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |