SKF工具包 UKEY加解密 JAVA接口调用UKEY DLL/SO驱动

最近公司需要开发基于UKEY方式的国密加解密,在网上找了一圈只找到唯一的龙脉科技的UEKY接口,也只有寥寥几个。经过一段时间的摸索终于写完测试通过。(使用了海泰方圆厂商提供的ukey,不管是哪个厂商,都是按照gj密码局要求的接口规范开发的,完全可以借鉴)

实现了SM4加解密和SM2加解密以及疏通了UKEY提供的所有JAVA接口。源码有需要的请v lalawangzi1986, 有偿指导。

贴一下测试过程的源码:



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.util.Arrays;
import java.util.Base64;
import java.util.List;

public class SKFUtil5 {

    public interface CLibrary extends Library {
        CLibrary INSTANCE = (CLibrary)
                Native.loadLibrary((Platform.isWindows() ? "C:\\Windows\\SysWOW64\\SKFAPI30987.dll" : "/opt/data/workdir/libSKFAPI-arm64.so"),
                        CLibrary.class);

        //设备操作
        long SKF_EnumDev(boolean bPresent, ByteByReference szNameList, LongByReference 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, LongByReference 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 pappname, PointerByReference happ);
        int SKF_CloseApplication(Pointer hDev);

        //访问控制
        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, LongByReference 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, LongByReference pulContainerType);
        int SKF_ExportCertificate(Pointer hContainer, boolean bSignFlag, byte[] pbCert, IntByReference pulCertLen);
        int SKF_ImportCertificate(Pointer hContainer, boolean bSignFlag, byte[] pbCert, IntByReference pulCertLen);

        //密码服务
        //加密
        int SKF_EncryptInit(Pointer hKey, BLOCKCIPHERPARAM.ByValue 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.ByValue DecryptParam);
        int SKF_Decrypt(Pointer hKey, byte[] pbEncryptedData, int ulEncryptedLen, byte[] pbData, IntByReference pulDataLen);
        int SKF_DecryptFinal(Pointer hKey, byte[] pbDecryptedData, IntByReference pulDecryptedDataLen);
        //导出导入
        //bSignFlag=TRUE表示导出签名公钥,FALSE表示导出加密公钥
        int SKF_ExportPublicKey(Pointer hContainer, boolean 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_ECCSignData(Pointer hContainer, byte[] pbData, int ulDataLen, ECCSIGNATUREBLOB pSignature);
        int SKF_ECCVerify(Pointer hDev, ECCPUBLICKEYBLOB pECCPubKeyBlob, byte[] pbData, int ulDataLen, ECCSIGNATUREBLOB pSignature);
        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_SetSymmKey(Pointer hDev, byte[] pbKey, int ulAlgID, PointerByReference phKey);
        int SKF_SetSymmKey(Pointer hDev, byte[] pbKey, NativeLong ulAlgID, PointerByReference phKey);

        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 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 static class ECCPRIVATEKEYBLOB extends Structure {
            public static final int ECC_MAX_MODULUS_BITS_LEN = 512;
            public int BitLen;
            public byte[] PrivateKey = new byte[ECC_MAX_MODULUS_BITS_LEN/8];
            @Override
            protected List<String> getFieldOrder() {
                return Arrays.asList(new String[] { "BitLen", "PrivateKey"});
            }
            public static class ByReference extends ECCPRIVATEKEYBLOB implements Structure.ByReference { }
            public static class ByValue extends ECCPRIVATEKEYBLOB implements Structure.ByValue {}
        }
        public static class ECCCIPHERBLOB extends Structure {
            public static final int ECC_MAX_XCOORDINATE_BITS_LEN = 512;
            public byte[] XCoordinate = new byte[ECC_MAX_XCOORDINATE_BITS_LEN/8];
            public byte[] YCoordinate = new byte[ECC_MAX_XCOORDINATE_BITS_LEN/8];
            public byte[] HASH = new byte[32];
            public int CipherLen;
            public byte[] Cipher = new byte[1];
            @Override
            protected List<String> getFieldOrder() {
                return Arrays.asList(new String[] { "XCoordinate", "YCoordinate", "HASH", "CipherLen", "Cipher"});
            }
            public static class ByReference extends ECCCIPHERBLOB implements Structure.ByReference { }
            public static class ByValue extends ECCCIPHERBLOB implements Structure.ByValue {}
        }
        public static class ECCSIGNATUREBLOB extends Structure {
            public static final int ECC_MAX_XCOORDINATE_BITS_LEN = 512;
            public byte[] r = new byte[ECC_MAX_XCOORDINATE_BITS_LEN/8];
            public byte[] s = new byte[ECC_MAX_XCOORDINATE_BITS_LEN/8];
            @Override
            protected List<String> getFieldOrder() {
                return Arrays.asList(new String[] { "r", "s"});
            }
            public static class ByReference extends ECCSIGNATUREBLOB implements Structure.ByReference { }
            public static class ByValue extends ECCSIGNATUREBLOB implements Structure.ByValue {}
        }
        public static class ENVELOPEDKEYBLOB extends Structure {
            public int Version;
            public int ulSymmAlgID;
            public int ulBits;
            public byte[] cbEncryptedPriKey = new byte[64];
            public ECCPUBLICKEYBLOB.ByReference PubKey;
            public ECCCIPHERBLOB.ByReference ECCCipherBlob;
            @Override
            protected List<String> getFieldOrder() {
                return Arrays.asList(new String[] { "Version", "ulSymmAlgID", "ulBits", "cbEncryptedPriKey", "PubKey", "ECCCipherBlob"});
            }
            public static class ByReference extends ENVELOPEDKEYBLOB implements Structure.ByReference { }
            public static class ByValue extends ENVELOPEDKEYBLOB implements Structure.ByValue {}
        }
        public static class FILEATTRIBUTE extends Structure {
            public byte[] FileName = new byte[32];
            public int FileSize;
            public int ReadRights;
            public int WriteRights;
            @Override
            protected List<String> getFieldOrder() {
                return Arrays.asList(new String[] { "FileName", "FileSize", "ReadRights", "WriteRights"});
            }
            public static class ByReference extends FILEATTRIBUTE implements Structure.ByReference { }
            public static class ByValue extends FILEATTRIBUTE implements Structure.ByValue {}
        }
    }

    public static void close(CLibrary ukey, Pointer p_hdev){
        long ret = ukey.SKF_DisConnectDev(p_hdev);
        if(ret != 0){
            //throw new Exception("SKF_VerifyPIN fail!");
            System.out.println("SKF_DisConnectDev fail!");
        }
    }

    public static void main(String[] args) throws Exception {
        CLibrary ukey = CLibrary.INSTANCE;

        long ret = -1l;
        ByteByReference deviceNameList = new ByteByReference();
        LongByReference deviceNameListLen = new LongByReference();
        ret = ukey.SKF_EnumDev(true, null, deviceNameListLen);
        long len = deviceNameListLen.getPointer().getLong(0);
        deviceNameListLen.setValue(len);
        ret = ukey.SKF_EnumDev(true, deviceNameList, deviceNameListLen);

        if(ret != 0l){
            System.out.println("未插入USBKey!");
            return ;
        }

        // 指向第一个设备
        String deviceName = deviceNameList.getPointer().getString(0);
        PointerByReference hDev = new PointerByReference();
        ret = ukey.SKF_ConnectDev(deviceName, hDev);
        if(ret != 0){
            System.out.println("连接设备失败");
            return ;
        }

        Pointer p_hdev = hDev.getValue();
        CLibrary.DEVINFO pDevInfo = new CLibrary.DEVINFO();
        //pDevInfo.clear();

        ret = ukey.SKF_GetDevInfo(p_hdev, pDevInfo);
        if(ret != 0){
            System.out.println("连接设备失败");
            return ;
        }
        String s = new String(pDevInfo.Label);

        int APP_NAME_SIZE = 256;


        ByteByReference bbr_applist = new ByteByReference();
        LongByReference lbr_pulSize = new LongByReference();
        //枚举设备中所存在的所有应用
        ret = ukey.SKF_EnumApplication(p_hdev, bbr_applist, lbr_pulSize);
        len = lbr_pulSize.getPointer().getLong(0);
        bbr_applist = new ByteByReference();
        lbr_pulSize = new LongByReference();
        lbr_pulSize.setValue(len);
        ret = ukey.SKF_EnumApplication(p_hdev, bbr_applist, lbr_pulSize);
        // Fuck!: bbr_applist最后有个空格!需要去掉!
        String app_name = bbr_applist.getPointer().getString(0).trim();
        PointerByReference pbr_happ = new PointerByReference();

        //打开指定的应用
        ret = ukey.SKF_OpenApplication(p_hdev, app_name, pbr_happ);
        Pointer p_happ = pbr_happ.getValue();

        LongByReference lbr_pulRetryCount = new LongByReference();

        ret = ukey.SKF_VerifyPIN(p_happ, 1, "111111", lbr_pulRetryCount);
        if(ret != 0){
            close(ukey, p_hdev);
            throw new Exception("SKF_VerifyPIN fail!");
        }

        //byte[] szContainerName = new byte[1024];
        IntByReference pulSize = new IntByReference();
        ret = ukey.SKF_EnumContainer(p_happ, null, pulSize);
        int len2 = pulSize.getValue();
        pulSize.setValue(len2);

        byte[] szContainerName = new byte[len2];
        ret = ukey.SKF_EnumContainer(p_happ, szContainerName, pulSize);
        String containerNames = new String(szContainerName, 0, pulSize.getValue());
        String [] containerNameList = containerNames.split("\0");

//        //创建指定容器DB
        PointerByReference phContainer = new PointerByReference();
        String containerName = "DB";

        ret = ukey.SKF_OpenContainer(p_happ, containerName, phContainer);
        if(ret != 0){
            close(ukey, p_hdev);
            throw new Exception("SKF_OpenContainer fail!");
        }
        Pointer hContainer = phContainer.getValue();

        LongByReference pulContainerType = new LongByReference();
        ret = ukey.SKF_GetContainerType(hContainer, pulContainerType);
        if(ret != 0){
            close(ukey, p_hdev);
            throw new Exception("SKF_GetContainerType fail!");
        }
        System.out.println("pulContainerType=" + pulContainerType.getValue());


        //下一步导入SM4秘钥
        String key = "1234567812345678";
        byte[] data = key.getBytes();

        //SGD_SMS4_ECB 0x00000401 SMS4 算法 ECB 加密模式
        long ulAlgID = 0x00000402;
        NativeLong ll = new NativeLong(ulAlgID);
        //int algid=1026;
        int algid=0x00000402;
        PointerByReference phKey = new PointerByReference();

        ret = ukey.SKF_SetSymmKey(p_hdev, data, ll, phKey);
        if(ret != 0){
            close(ukey, p_hdev);
            throw new Exception("SKF_SetSymmKey fail!");
        }

        Pointer hKey = phKey.getValue();


        ret = ukey.SKF_CloseApplication(p_happ);
        if(ret != 0){
            close(ukey, p_hdev);
            throw new Exception("SKF_CloseApplication fail!");
        }
        ret = ukey.SKF_DisConnectDev(p_hdev);
        if(ret != 0){
            //throw new Exception("SKF_VerifyPIN fail!");
            System.out.println("SKF_DisConnectDev fail!");
        }
        p_happ = null;

    }


}

  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值