Java调用UK动态库SKF接口(dll/so)——JNA的实现

打印 上一主题 下一主题

主题 531|帖子 531|积分 1593

Java调用UK动态库SKF接口(dll/so)——JNA的实现

   个人对Java语音了解有限,由于工作上的原因,写了一个的demo,仅供参考
  
  
   情况:
  
      
  • IntelliJ IDEA Community Edition 2024.1  
  • wiindows10
  1-项目搭建

1.1-创建项目

  1. 1- 新建项目:选择Maven Archetype
  2.         a- Archetype:任意添加一个,默认第一个(org.apache.maven.archetypes:maven-archetype-archetype)
复制代码
1.2-JNA依靠

在项目根目录下的pom.xml添加JNA依靠
  1. <dependencies>
  2.     <!-- 添加JNA依赖 -->
  3.     <dependency>
  4.         <groupId>net.java.dev.jna</groupId>
  5.         <artifactId>jna</artifactId>
  6.         <version>5.10.0</version> <!-- 请检查并使用最新版本 -->
  7.     </dependency>
  8. </dependencies>
复制代码
1.3-目录创建

在src\mian下创建java目录,后续的代码文件将在这个目录下创建完成
2-Java SKFApi接口类的创建

   涉及的内容:
  
      
  • 相关数据类型(各结构体):  
  • SKF接口  
  • 算法ID
  2.1-数据结构的定义

示例:
C的结构体定义:
  1. typedef struct Struct_Version{
  2.    
  3.         BYTE major;
  4.         BYTE minor;
  5. }VERSION;
复制代码
Java-JNA的对应的定义:
   
      
  • getFieldOrder:必须存在的方法,里面的字符串跟结构体变量的顺序保持一致,没有会报错
      
  • ByReference和ByValue:非必须的,在结构体类内部再定义两个静态类ByReference和ByValue 用于表示值传递还是引用传递,发起加上。
      
  • 可增加其他方法:如果有需要对结构体完成某些操纵,可在后面增加方法,后面的部分结构体的部分中我会增加get和set方法,因为SKF接口中有涉及到将结构体转为byte*类型,或将byte*转为结构体的,以是增加get方法将结构体转为byte数组,set方法将byte数组转为结构体。

  1. public static class VERSION extends Structure {
  2.    
  3.         public int major;
  4.         public int minor;
  5.             // 定义值传递和指针传递类
  6.         public static class ByReference extends VERSION implements Structure.ByReference {
  7.    
  8.             //指针和引用的传递使用ByReference
  9.         }
  10.         public static class ByValue extends VERSION implements Structure.ByValue {
  11.    
  12.             //拷贝参数传递使用ByValue
  13.         }
  14.         @Override
  15.         protected List<String> getFieldOrder() {
  16.    
  17.             return Arrays.asList(new String[]{
  18.    "major", "minor"});
  19.         }
  20.     }
复制代码
2.2-SKF句柄相关

   SKF涉及到的句柄有:设备句柄、应用句柄、容器句柄、会话密钥句柄、哈希句柄
  C中的SKF相关的句柄:
  1. DEVHANDLE *phDev = NULL;                                 // 设备句柄
  2. HAPPLICATION *phApplicatio = NULL;                  // 应用句柄
  3. HCONTAINER *phContaine = NULL;                        // 容器句柄
  4. HANDLE *phKeyHandle = NULL;                                // 会话密钥句柄
  5. HANDLE *phHash = NULL;                                        // 哈希句柄
复制代码
Java-JNA的SKF相关的句柄:
  1. // 句柄的定义
  2. PointerByReference phDev = new PointerByReference();// 设备句柄
  3. PointerByReference phApp = new PointerByReference();// 应用句柄
  4. PointerByReference phContainer = new PointerByReference();// 容器句柄
  5. PointerByReference sessionKey = new PointerByReference();// 会话密钥句柄
  6. PointerByReference pHash = new PointerByReference(); // 哈希句柄
  7. // 在获取句柄的时候传PointerByReference引用,在后续使用句柄的时候用getValue的值,以获取设备句柄,和使用设备句柄接口定义为例:连接设备、断开连接
  8. long SKF_ConnectDev(String szName, PointerByReference phDev); // 连接设备
  9. long SKF_DisConnectDev(Pointer hDev);//断开连接
  10. // 示例
  11. PointerByReference phDev = new PointerByReference();
  12. SKF_ConnectDev(deviceName, phDev)
  13. // 调用SKF_ConnectDev接口后,用getValue方法获取指针
  14. Pointer hDev = phDev.getValue();
  15. SKF_DisConnectDev(hDev)
复制代码
2.3-注意事项

   
      
  • SKF接口中定义为BOOL类型的参数,在Java-JNA中用int类型表示:1表示true,0表示false
         
    • 原因:如果用Java的Boolean类型传,可能会出现传true和false的效果一样   
       
  • 大小端序问题:
         
    • 将数据以byte数组输出大概将byte数据输入(或转为结构体)时要注意此问题,SKF接口是小端序输出的。   
      
  2.4-SKFApi内容

   请根据实际情况加载的动态库:
  1. import com.sun.jna.*;
  2. import com.sun.jna.ptr.ByteByReference;
  3. import com.sun.jna.ptr.IntByReference;
  4. import com.sun.jna.ptr.LongByReference;
  5. import com.sun.jna.ptr.PointerByReference;
  6. import java.nio.ByteBuffer;
  7. import java.nio.ByteOrder;
  8. import java.util.Arrays;
  9. import java.util.List;
  10. public interface SkfApi extends Library {
  11.    
  12.     SkfApi INSTANCE = Native.load("your_dll_name", SkfApi.class);
  13.     //设备操作
  14.     long SKF_EnumDev(int bPresent, ByteByReference szNameList, IntByReference pulSize);
  15.     long SKF_ConnectDev(String szName, PointerByReference phDev);
  16.     long SKF_DisConnectDev(Pointer hDev);
  17.     long SKF_GetDevInfo(Pointer hDev, DEVINFO pDevInfo);
  18.     //应用操作
  19.     int SKF_EnumApplication(Pointer hDev, ByteByReference szAppName, IntByReference pulSize);
  20.     int SKF_CreateApplication(Pointer hDev, String szAppName, String szAdminPin, int dwAdminPinRetryCount, String szUserPin, int dwUserPinRetryCount, int dwCreateFileRights, PointerByReference hApp);
  21.     int SKF_OpenApplication(Pointer hDev, String appName, PointerByReference hApp);
  22.     int SKF_CloseApplication(Pointer hApp);
  23.     //访问控制
  24.     int SKF_ChangeDevAuthKey(Pointer hDev, byte[] pbKeyValue, int ulKeyLen);
  25.     int SKF_DevAuth(Pointer hDev, byte[] pbAuthData, int ulLen);
  26.     int SKF_ChangePIN(Pointer hApplication, int ulPINType, String oldPIN, String newPIN, IntByReference pulRetryCount);
  27.     int SKF_GetPINInfo(Pointer hApplication, int ulPINType, IntByReference pulMaxRetryCount, IntByReference pulRemainRetryCount, IntByReference pbDefaultPin);
  28.     int SKF_VerifyPIN(Pointer hApplication, int ulPINType, String szPIN, IntByReference pulRetryCount);
  29.     int SKF_UnblockPIN(Pointer hApplication, String szAdminPIN, String szNewUserPIN, IntByReference pulRetryCount);
  30.     int SKF_ClearSecueState(Pointer hApplication);
  31.     //容器管理
  32.     int SKF_CreateContainer(Pointer hApplication, String szContainerName, PointerByReference phContainer);
  33.     int SKF_DeleteContainer(Pointer hApplication, String szContainerName);
  34.     int SKF_EnumContainer(Pointer hApplication, byte[] szContainerName, IntByReference pulSize);
  35.     int SKF_OpenContainer(Pointer hApplication, String szContainerName, PointerByReference phContainer);
  36.     int SKF_CloseContainer(Pointer hContainer);
  37.     int SKF_GetContainerType(Pointer hContainer, IntByReference pulContainerType);
  38.     // 密码服务
  39.     // int SKF_ExportCertificate(Pointer hContainer, boolean bSignFlag, byte[] pbCert, IntByReference pulCertLen);
  40.     // 接口中的boolean 都要改为int类型,1表示true,0表示false,如果是传boolean类型,不管是传true还是false,实际结果否是false的结果
  41.     int SKF_ExportCertificate(Pointer hContainer, int bSignFlag, byte[] pbCert, IntByReference pulCertLen);
  42.     //int SKF_ImportCertificate(Pointer hContainer, boolean bSignFlag, byte[] pbCert, IntByReference pulCertLen);
  43.     // 接口中的boolean 都要改为int类型,1表示true,0表示false,如果是传boolean类型,不管是传true还是false,实际结果否是false的结果
  44.     int SKF_ImportCertificate(Pointer hContainer, int bSignFlag, byte[] pbCert, IntByReference pulCertLen);
  45.     int SKF_EncryptInit(Pointer hKey, BLOCKCIPHERPARAM EncryptParam);
  46.     int SKF_Encrypt(Pointer hKey, byte[] pbData, int ulDataLen, byte[] pbEncryptedData, IntByReference pulEncryptedLen);
  47.     int SKF_EncryptUpdate(Pointer hKey, byte[] pbData, int ulDataLen, byte[] pbEncryptedData, IntByReference pulEncryptedLen);
  48.     int SKF_EncryptFinal(Pointer hKey, byte[] pbEncryptedData, IntByReference ulEncryptedDataLen);
  49.     int SKF_DecryptInit(Pointer hKey, BLOCKCIPHERPARAM DecryptParam);
  50.     int SKF_Decrypt(Pointer hKey, byte[] pbEncryptedData, int ulEncryptedLen, byte[] pbData, IntByReference pulDataLen);
  51.     int SKF_DecryptFinal(Pointer hKey, byte[] pbDecryptedData, IntByReference pulDecryptedDataLen);
  52.     //int SKF_ExportPublicKey(Pointer hContainer, boolean bSignFlag, byte[] pbBlob, IntByReference pulBlobLen);
  53.     // 接口中的boolean 都要改为int类型,1表示true,0表示false,如果是传boolean类型,不管是传true还是false,实际结果否是false的结果
  54.     int SKF_ExportPublicKey(Pointer hContainer, int bSignFlag, byte[] pbBlob, IntByReference pulBlobLen);
  55.     int SKF_GenECCKeyPair(Pointer hContainer, NativeLong ulAlgId, ECCPUBLICKEYBLOB pBlob);
  56.     int SKF_DigestInit(Pointer hDev, int ulAlgID, ECCPUBLICKEYBLOB pPubKey, byte[] pucID, int ulIDLen, PointerByReference phHash);
  57.     int SKF_Digest(Pointer hHash, byte[] pbData, int ulDataLen, byte[] pbHashData, IntByReference pulHashLen);
  58.     int SKF_DigestUpdate(Pointer hHash, byte[] pbData, int ulDataLen);
  59.     int SKF_DigestFinal(Pointer hHash, byte[] pHashData, IntByReference pulHashLen);
  60.     int SKF_RSASignData(Pointer hContainer,byte[] pbData, int ulDataLen,byte[]pbSignature,IntByReference pulSignLen);
  61.     int SKF_RSAVerify(Pointer hContainer,RSAPUBLICKEYBLOB pPubKey,byte[] pbData, int ulDataLen,byte[]pbSignature,int ulSignLen);
  62.     int SKF_ECCSignData(Pointer hContainer, byte[] pbData, int ulDataLen, ECCSIGNATUREBLOB pSignature);
  63.     int SKF_ECCVerify(Pointer hDev, ECCPUBLICKEYBLOB pECCPubKeyBlob, byte[] pbData, int ulDataLen, ECCSIGNATUREBLOB pSignature);
  64.     int SKF_RSAExportSessionKey(Pointer hContainer, int ulAlgId, RSAPUBLICKEYBLOB pPubKey, byte[] pData, IntByReference pulDataLen, PointerByReference phSessionKey);
  65.     int SKF_ECCExportSessionKey(Pointer hContainer, int ulAlgId, ECCPUBLICKEYBLOB pPubKey, ECCCIPHERBLOB pData, PointerByReference phSessionKey);
  66.     int SKF_ImportECCKeyPair(Pointer hContainer, ENVELOPEDKEYBLOB pEnvelopedKeyBlob);
  67.     int SKF_ExtECCSign(Pointer hDev, ECCPRIVATEKEYBLOB pECCPriKeyBlob, byte[] pbData, int ulDataLen, ECCSIGNATUREBLOB pSignature);
  68.     int SKF_ExtECCVerify(Pointer hDev, ECCPUBLICKEYBLOB pECCPubKeyBlob, byte[] pbData, int ulDataLen, ECCSIGNATUREBLOB pSignature);
  69.     int SKF_ExtECCEncrypt(Pointer hDev, ECCPUBLICKEYBLOB pECCPubKeyBlob, byte[] pbPlainText, int ulPlainTextLen, ECCCIPHERBLOB pCipherText);
  70.     int SKF_ExtECCDecrypt(Pointer hDev, ECCPRIVATEKEYBLOB pECCPriKeyBlob, ECCCIPHERBLOB pCipherText, byte[] pbPlainText, IntByReference pulPlainTextLen);
  71.     int SKF_ImportSessionKey(Pointer hCnt, int ulAlgId, byte[] pbWrapedData, int ulWrapedLen, PointerByReference hkey);
  72.     int SKF_SetSymmKey(Pointer hDev, byte[] pbKey, int ulAlgID, PointerByReference phKey);
  73.     int SKF_CloseHandle(Pointer hHandle);
  74.     public static class VERSION extends Structure {
  75.    
  76.         public int major;
  77.         public int minor;
  78.         public static class ByReference extends VERSION implements Structure.ByReference {
  79.    
  80.         }
  81.         public static class ByValue extends VERSION implements Structure.ByValue {
  82.    
  83.         }
  84.         @Override
  85.         protected List<String> getFieldOrder() {
  86.    
  87.             return Arrays.asList(new String[]{
  88.    "major", "minor"});
  89.         }
  90.     }
  91.     public static class DEVINFO extends Structure {
  92.    
  93.         public VERSION Version;
  94.         public byte[] Manufacturer = new byte[64];
  95.         public byte[] Issuer = new byte[64];
  96.         public byte[] Label = new byte[32];
  97.         public byte[] SerialNumber = new byte[32];
  98.         public VERSION HWVersion;
  99.         public VERSION FirmwareVersion;
  100.         public int AlgSymCap;
  101.         public int AlgAsymCap;
  102.         public int AlgHashCap;
  103.         public int DevAuthAlgId;
  104.         public int TotalSpace;
  105.         public int FreeSpace;
  106.         public byte[] Reserved = new byte[64];
  107.         public static class ByReference extends DEVINFO implements Structure.ByReference {
  108.    
  109.         }
  110.         public static class ByValue extends DEVINFO implements Structure.ByValue {
  111.    
  112.         }
  113.         @Override
  114.         protected List<String> getFieldOrder() {
  115.    
  116.             return Arrays.asList(new String[]{
  117.    "Version", "Manufacturer", "Issuer", "Label", "SerialNumber", "HWVersion", "FirmwareVersion", "AlgSymCap", "AlgAsymCap", "AlgHashCap", "DevAuthAlgId" , "TotalSpace", "FreeSpace", "Reserved"});
  118.         }
  119.     }
  120.     public static class BLOCKCIPHERPARAM extends Structure {
  121.    
  122.         public byte[] IVS = new byte[32];
  123.         public int IVLen = 0;
  124.         public int PaddingType = 0;
  125.         public int FeedBitLen = 0;
  126.         @Override
  127.         protected List<String> getFieldOrder() {
  128.    
  129.             return Arrays.asList(new String[]{
  130.    "IVS", "IVLen", "PaddingType", "FeedBitLen"});
  131.         }
  132.         public static class ByReference extends BLOCKCIPHERPARAM implements Structure.ByReference {
  133.    
  134.         }
  135.         public static class ByValue extends BLOCKCIPHERPARAM implements Structure.ByValue {
  136.    
  137.         }
  138.         public void setBlobCipherParam(byte[] IV, int ivLen, int PaddingType, int FeedBitLen){
  139.    
  140.             this.IVS = IV;
  141.             this.IVLen = ivLen;
  142.             this.PaddingType = PaddingType;//填充方式,0表示不填充,1表示按照PKCS5方式进行填充。
  143.             this.FeedBitLen = FeedBitLen;
  144.         }
  145.     }
  146.     public static class ECCPUBLICKEYBLOB extends Structure {
  147.    
  148.         public static final int ECC_MAX_XCOORDINATE_BITS_LEN = 512;
  149.         public static final int ECC_MAX_YCOORDINATE_BITS_LEN = 512;
  150.         public int BitLen;
  151.         public byte[] XCoordinate = new byte[ECC_MAX_XCOORDINATE_BITS_LEN / 8];
  152.         public byte[] YCoordinate = new byte[ECC_MAX_YCOORDINATE_BITS_LEN / 8];
  153.         @Override
  154.         protected List<String> getFieldOrder() {
  155.    
  156.             return Arrays.asList(new String[]{
  157.    "BitLen", "XCoordinate", "YCoordinate"});
  158.         }
  159.         public static class ByReference extends ECCPUBLICKEYBLOB implements Structure.ByReference {
  160.    
  161.         }
  162.         public static class ByValue extends ECCPUBLICKEYBLOB implements Structure.ByValue {
  163.    
  164.         }
  165.         public byte[] getEccPublicBlob() {
  166.    
  167.             byte[] eccPublicBlob = new byte[132];
  168.             int bitLenInt = this.BitLen;
  169.             byte[] bitLenBytes = new byte[3];
  170.             bitLenBytes[2] = (byte) (bitLenInt & 0xFF); // 最低有效字节
  171.             bitLenBytes[1] = (byte) ((bitLenInt >> 8) & 0xFF);
  172.             bitLenBytes[0] = (byte) ((bitLenInt >> 16)
复制代码
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

美丽的神话

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表