使用GVSM(国密)密码机集群

更新时间:
复制 MD 格式

本文以GVSM为例指导您如何快速上手使用加密服务。

注意事项

前提条件

  • 已购买密码机。具体操作,请参见购买密码机

  • 已购买Windows系统的ECS实例,且ECS实例需要和密码机实例在同一VPC。具体操作,请参见Windows系统实例快速入门

    说明

    ECS实例用于安装密码机管理工具,而非用于业务服务器。

步骤一:创建并激活集群

说明

如果您在购买密码机时配置了集群信息,HSM会在您下单后自动创建集群,请跳过本步骤。

一个集群包括一个主密码机与若干个子密码机,同一集群内所有密码机必须属于同一VPC,可以属于同一或不同子网。

  1. 启用主密码机实例。

    1. 访问加密服务控制台的虚拟密码机实例页面,在顶部菜单栏,选择目标地域。

    2. 虚拟密码机实例页面,定位到已创建的密码机实例,单击操作列的启用

    3. 密码机实例配置对话框,配置密码机实例,然后单击确定。配置成功后,密码机实例的状态变为已启用

      配置项

      说明

      所属的VPC网络ID

      选择密码机实例需要绑定的VPC。

      重要

      需要与您的ECS实例绑定的VPC是同一个。

      所属的VPC子网

      选择密码机实例所属的VPC子网网段。

      分配私网IP地址

      为密码机实例分配一个私网IP地址。

      重要
      • 私网IP地址必须是所属的VPC子网网段中的IP地址,否则配置将会失败。

      • 末位为253、254、255IP地址为系统保留地址,请勿使用。

      设置密码机实例白名单

      设置访问该密码机实例的白名单。您可以输入单个IP地址或网段地址,每行输入1条数据,最多可以输入10条数据。

      • 未设置白名单:所有IP地址都能访问密码机实例。

      • 设置了白名单:仅支持白名单内的访问请求,不在白名单内的访问请求将被拒绝。

      重要
      • 如果您创建了集群并设置了集群的白名单,那么集群的白名单优先级高于集群中密码机实例的白名单。

        例如,集群中密码机实例的白名单为10.10.10.10,集群的白名单为172.16.0.1,则您只能通过172.16.0.1访问集群中的密码机实例。

      • 不支持配置为0.0.0.0/0(放行所有来源IP)。

        基于安全考虑,不推荐您放行所有来源IP。如果因临时测试等原因确实需要放行所有来源IP,不配置白名单即可。

  2. 创建密码机集群。

    1. 定位到主密码机实例,单击操作列的创建集群

    2. 创建并激活集群面板,创建集群信息。

      配置项

      说明

      集群名称

      自定义集群的名称。名称不能重复且长度不允许超过24个字符。

      设置集群访问白名单

      允许访问集群的IP地址。如果未设置白名单,则所有IP地址都能访问集群,如果设置了白名单,则不在白名单内的访问请求将被拒绝。

      您可以输入单个IP地址或网段地址,每行输入1条数据,最多可以输入10条数据。

      重要
      • 集群的白名单优先级高于集群中密码机实例的白名单。例如,您设置的集群中密码机实例的白名单为10.10.10.10,集群的白名单为172.16.0.1,则您只能通过172.16.0.1访问集群中的密码机实例。

      • 不支持配置为0.0.0.0/0(放行所有来源IP)。

        基于安全考虑,不推荐您放行所有来源IP。如果因临时测试等原因确实需要放行所有来源IP,不配置白名单即可。

      指定集群的交换机(2~4个)

      根据业务需要选择可用区的交换机。

      在密码机实例集群中,您至少配置2个交换机才能成功创建并激活集群。

    3. 初始化密码机实例,然后单击下一步

      只有主密码机状态为已初始化时才能激活集群。初始化主密码机的具体操作如下:

      初始化方式

      操作步骤

      方式一:在加密服务控制台一键初始化

      重要

      使用一键初始化,您的密码机必须是通用密码机GVSM且您没有使用UKEY的需求。

      1. 创建并激活集群面板的最下方,单击一键初始化主密码机实例

      2. 初始化实例对话框,单击确定

      初始化预计需要1~5分钟时间,请耐心等待。初始化完成后,单击已选主密码机:后的update图标,状态会显示已初始化,该状态下请勿重复初始化。

      方式二:使用密码机实例管理工具初始化

      重要

      密码机客户端管理工具只支持在Windows系统运行。

      创建并激活集群面板的最下方,单击下载密码机实例管理工具

      解压获取密码机软件包,参考密码机软件包中的用户管理手册的《原始初始化》章节,完成初始化操作。

    4. 根据页面提示,添加子密码机到集群,然后单击完成

(可选)步骤二:生成证书并配置双向TLS认证

GVSM(国密)支持在购买密码机时选择自动生成证书,此时HSM会自动生成证书,您只需在客户端SDK侧配置证书,HSM会自动在服务端加密机内部署证书。

  1. 在客户端部署证书。

    请在控制台下载客户端证书,并自行部署至您的客户端。

    1. 请在密码机详情页面,单击获取集群证书。在下载的文件夹中包含下列文件:

      certs/
      ├── client.p12 (PKCS12格式客户端证书,包含客户端证书以及私钥)
      ├── client.pem (PEM格式客户端证书)
      ├── rootca.key (CA私钥)
      ├── rootca.pem (PEM格式CA证书)
      ├── server.p12 (PKCS12格式服务端证书)
      └── passphrase (PKCS12格式证书(后缀为.p12)的证书保护口令)
    2. 请将client.p12、rootca.pem部署至客户端,同时客户端配置文件中需要配置client.p12、rootca.pem的文件路径以及passphrase值。详细介绍,请参见控制台下载的软件包中的参考文档。

  2. 在服务端部署证书。

    HSM会自动将证书部署至密码机,您无需关注。

重要

证书的有效期默认为10年,到期前HSM会自动生成证书并轮转服务端证书,建议您不要使用密码机管理工具创建UKEY管理员,创建UKEY管理员会导致证书轮转失败。

步骤三:同步集群数据

本文以GVSM类型的密码机为例。购买GVSM时会根据您配置的集群数据自动创建集群,您需要根据集群类型确定是否需要同步集群数据。

  • 集群类型手动同步集群时:第一次创建并激活集群后或者主密码机数据变更后,都需要执行同步集群操作,扩展集群时无需同步集群。

  • 集群类型自动同步集群时:无需同步集群,主密码机新创建的密钥、配置的SSL证书以及用户信息等,都会自动同步到子密码机上。

警告

同步集群预计需要5分钟,请在业务空闲期进行同步,以免影响业务运行。

  1. 虚拟密码机实例页面,找到目标主密码机实例,在实例列表的集群类型列查看同步类型(手动同步集群/自动同步集群)。

    当集群类型为手动同步集群时,执行同步集群操作。

  2. 操作列单击同步集群,在弹出的对话框中,再次单击同步集群

步骤四:创建密钥并使用密钥加解密

在密码机软件包中找到密码机的开发手册、SDK测试程序等,您可以参考开发手册,调用API接口使用密码机实例。

说明

您可以在加密服务控制台的虚拟密码机实例页面,单击目标密码机实例的规格列,下载密码机实例管理工具 ,解压后即得到密码机软件包。

以通用密码机GVSM为例,在解压后的阿里云加密服务GVSM软件包>SDK>JAVA>服务器密码机接口资料>测试demo目录中找到测试用例APITest.java,使用该测试用例来测试密码机实例。代码示例如下:

说明

您需要将用例中的IP地址(192.168.XX.XX)修改为密码机实例分配的私网IP地址。

package cn.tass.hsm;

import cn.tass.SJJ1507.devices.RasKeyUtils;
import cn.tass.common.kits.Padding;
import cn.tass.exceptions.TAException;
import cn.tass.hsm.GHSMAPI;
import cn.tass.kits.Forms;
import cn.tass.hsm.Host;
import cn.tass.hsm.LogConfig;
import cn.tass.util.encoders.Base64;
import org.junit.Test;

import javax.naming.ConfigurationException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class APITest {
    LogConfig logConfig = new LogConfig("error", "./");
    Host host1 = new Host("GHSM", -3, "192.168.XX.XX", 8019, 5);
    List<Host> hosts = new ArrayList<Host>() {{
        add(host1);
    }};

    String config =
            "{"
                    + "[LOGGER];"
                    + "logsw=debug,error;logPath=./;"
                    + "[HOST 1];"
                    + "hsmModel=GHSM;"
                    + "host=192.168.XX.XX;linkNum=-3;"
                    + "port=8019;"
                    + "timeout=5;"
                    + "}";

//    GHSMAPI api = GHSMAPI.getInstance(hosts, logConfig);
    GHSMAPI api = GHSMAPI.getInstance(config);

    /**
     * LMK加密的对称密钥
     */
    byte[] symmetricKey = Forms.hexStringToByteArray("669C1CEDDA****5D727EA727558B5");
    byte[] verifyValue = Forms.hexStringToByteArray("BD85****4D88");

    byte[] symmetricKey1 = Forms.hexStringToByteArray("93EF12C958****C3EFDBC7B37642D");
    byte[] verifyValue1 = Forms.hexStringToByteArray("7830****B8E6");
    /**
     * LMK加密的会话密钥密文
     */
    byte[] symmetricKeyKEK = Forms.hexStringToByteArray("2E80A42018****CF639F644629E8");
    /**
     * 会话密钥的校验值
     */
    byte[] verifyValueMAC = Forms.hexStringToByteArray("734D****3E38");
    /**
     * 保护密钥保护的密文
     */
    byte[] protectionKey = Forms.hexStringToByteArray("2EACE685C5EB2638D120*****CD44210B43C894A77C");
    /**
     * 保护密钥保护的密文的MAC
     */
    byte[] protectionMAC = Forms.hexStringToByteArray("0CB8****E487");

    /**
     * RSA DER编码的公钥
     */
    byte[] publicKeyRSA = Forms.hexStringToByteArray("308186028180E14CAAFFCEC6D014457D7CA3E********1299BDBC17690C8E70F7BFA10EA02450805DA4C6CDC38BFBF1349C95B81A88177BA31C08")
     * RSA LMK加密的私钥
     */
    byte[] privateKeyRSA = Forms.hexStringToByteArray("00202703D0652C7027B7D94B45A896646A9*********1B3CC00E37BE933055D5C00E37BE933055D54718ADDAA677519BD9C054CA249B43888")
    /**
     * RSA 保护密钥加密的私钥
     */
    byte[] privateKeyRSAKEK = Forms.hexStringToByteArray("6B2FB2BCC75604ABF5761FFA1027FF16324*********63AD3B57BD89059D5799974B4E5E9453763D94E682C629C4617C4E5393E9DDBFB")
    /**
     * RSA MAC
     */
    byte[] privateKeyRSAKEKMAC = Forms.hexStringToByteArray("701A****9760");

    /**
     * KEK 加密的RSA私钥
     */
    byte[] privateKeyKEK = Forms.hexStringToByteArray("7A833CC0FAFBA6EC063DF4827B8FD91FF4B9A69F********1E02C312ABFC68F454D11EFCF1E0609584D06B09A08599D7A0BF5D63BB9F");
    /**
     * KEK RSA 私钥MAC
     */
    byte[] privateKeyRSAMAC = Forms.hexStringToByteArray("06E5****36DE");

    /**
     * KEK 加密的SM2私钥
     */
    byte[] privateKeySM2KEK = Forms.hexStringToByteArray("D3C5F579038C8BF34698****EF6044210B43C894A77C");
    /**
     * KEK SM2 私钥MAC
     */
    byte[] privateKeySM2MAC = Forms.hexStringToByteArray("83E4****0D15");


    /**
     * SM2 der编码的公钥
     */
    byte[] privateKeySM2DER = Forms.hexStringToByteArray("3059301306072A8648CE3D020106082A811CCF55********42A53790967A1368B7084F6EFED51FC848D1E3B5370A99BDCB64D17C2F");
    /**
     * SM2 lmk加密的私钥
     */
    byte[] privateKeySM2 = Forms.hexStringToByteArray("66C9DDB0D6400EE05947****21908C4F5CA6457B435F");
    /**
     * SM2 保护密钥保护的私钥
     */
    byte[] privateKeyKEKSM2 = Forms.hexStringToByteArray("D3C5F579038C8BF3A162****F99644210B43C894A77C");
    /**
     * SM2 MAC
     */
    byte[] privateKeyKEKSM2MAC = Forms.hexStringToByteArray("B982****8232");

    /**
     * 随机生成的sm2密钥 1002
     */
    byte[] publicSM2 = Forms.hexStringToByteArray("3059301306072A8648CE3D020106082A811CCF55********6913D902C4C9B8A84A3F96ADDD7BEF537D61404D56E58A68C756AEFD40");
    byte[] privateSM2 = Forms.hexStringToByteArray("6F26783DCE6D45B84D3F****2FA68D1A3B721C09BB28");

    /**
     * MD5 算法算出的数据摘要
     */
    byte[] md5 = Forms.hexStringToByte("D41D8CD98F00B204E9800998ECF8427E");
    /**
     * SM3 算法算出的数据摘要
     */
    byte[] sm3 = Forms.hexStringToByte("E559D3DE421E81967DD68B28B55E0C26B03FCE10B8A8E5C4E6067497729D40D3");

    /**
     *
     */
    byte[] b = Forms.hexStringToByteArray("00000000000000000000000000000000");

    public APITest() throws TAException, ConfigurationException {
    }


    /**
     * 产生对称密钥
     *
     * @throws TAException
     */
    @Test
    public void genSymmKey() throws TAException {
        ArrayList<byte[]> bytes = api.genSymmKey(3);
        System.out.println("LMK加密的对称密钥:"  + Forms.byteToHexString(bytes.get(0)));
        System.out.println("对称密钥的校验值:"  + Forms.byteToHexString(bytes.get(1)));

    }

    ///////////////////////////////////////////////////////////////////////////
    // 1015 测试数据
    ///////////////////////////////////////////////////////////////////////////

    byte[] sm4Key = Forms.hexStringToByte("EE828FCCFA****468B1FECCE81192");
    byte[] sm4CV = Forms.hexStringToByte("BCC2****2764");

    byte[] sm4ProKeyCipher = Forms.hexStringToByte("7C78B0D533****E9277504181C23F");
    byte[] sm4ProKeyCipherCV = Forms.hexStringToByte("8849****FB73");

    byte[] newSM4 = Forms.hexStringToByte("AE62E4E90F****AECE0AC9923B885");
    byte[] newSM4KeyMAC = Forms.hexStringToByte("F7EBEA9FD3****4E7EAAC9B7BE362");
    byte[] newSM4KeyTag = Forms.hexStringToByte("7C05A01A54****E0C8597DBED6D6D");

    byte[] sm4Key2 = Forms.hexStringToByte("40F7B1FA35****EB13491B119A4AB");
    byte[] sm4Key2CV = Forms.hexStringToByte("955C****9C51");

    /**
     * 产生对称密钥,保护密钥保护输出
     *
     * @throws TAException
     */
    @Test
    public void generateProtectionKey() throws TAException {
        /**
         * sm4
         * LMK加密的对称密钥:B36847D6E8****4EEB65558A2626C
         * 对称密钥的校验值:713C****2AAB
         */
        ArrayList<byte[]> bytes = api.proGenSymmKey(Forms.hexStringToByteArray("B36847D6E8****4EEB65558A2626C"),
                TACryptConst.KEY_ALG_SM4, Forms.hexStringToByteArray("713C****2AAB"), TACryptConst.KEY_ALG_SM4, b,
                TACryptConst.ENC_MODE_GCM,b, b);
        System.out.println("LMK加密的会话密钥密文:" + Forms.byteToHexString(bytes.get(0)));
        System.out.println("会话密钥的校验值:" + Forms.byteToHexString(bytes.get(1)));
        System.out.println("保护密钥加密的会话密钥密文:" + Forms.byteToHexString(bytes.get(2)));
        System.out.println("会话密钥的MAC值:" + Forms.byteToHexString(bytes.get(3)));
        System.out.println("tags:" + Forms.byteToHexString(bytes.get(4)));

    }

    /**
     * 对称密钥加解密数据
     *
     * @throws TAException
     */
    @Test
    public void generalDataEnc() throws TAException {
//        byte[] bytes = api.symmKeyDataEnc(sm4Key,TACryptConst.ENC_MODE_ECB,TACryptConst.KEY_TYPE_RULE, TACryptConst.KEY_ALG_SM4,
//                "0000000000000000".getBytes(), b);
//        System.out.println("SM4加密结果:" + Forms.byteToHexString(bytes));
//        byte[] bytes1 = api.generalDataDec(sm4Key,TACryptConst.ENC_MODE_ECB, TACryptConst.KEY_TYPE_RULE, TACryptConst.KEY_ALG_SM4, bytes, b);
//        System.out.println("SM4解密结果:" + new String(bytes1));
//        byte[] paddingData = Padding.PKCS5Padding(Forms.hexStringToByte("30820122300D06092A864886F70D010101050003********FE2D80A275BF5D096D2E07BA9ED5A75A10D425B03B84BB57990203010001"), 16);
//        byte[] bytes = api.symmKeyDataEnc(28,TACryptConst.ENC_MODE_CBC,TACryptConst.KEY_TYPE_RULE, TACryptConst.KEY_ALG_AES128,
//                paddingData, b);
//        System.out.println("AES加密结果:" + Forms.byteToHexString(bytes));
        byte[] bytes1 = api.generalDataDec(Forms.hexStringToByte("789F01F9CC****429D7EAB215ABA1"),TACryptConst.ENC_MODE_CBC, TACryptConst.KEY_TYPE_RULE, TACryptConst.KEY_ALG_AES128,
                Forms.hexStringToByte("AE6BA9133D0D4BB0090882E33F03D905D7797852********B1C0079352310E974EB1155A759374004095E2256B0ADC3BFFFF150AF071"), b);
        System.out.println("AES解密结果:" + Forms.byteToHexString(bytes1));
    }




    /**
     * 对称密钥(受保护密钥保护)加解密数据
     *
     * @throws TAException
     */
    @Test
    public void protectionKeyEncrypt() throws TAException {
        ArrayList<byte[]> bytes = api.proKeyEncData(sm4Key, TACryptConst.KEY_ALG_SM4, sm4CV,
                Forms.hexStringToByte("C0C64CD82E3B2DC8C8F4****F5BA4F0BCF7AC04E08E8"),
                b, Forms.hexStringToByte("75F2C068A5****F0BCF7AC04E08E8"), TACryptConst.ENC_MODE_CBC,
                b, new byte[0], new byte[0], TACryptConst.KEY_ALG_AES256, 1, 3,
                new byte[16], TACryptConst.KEY_ALG_SM4, TACryptConst.ENC_MODE_GCM,
                "mingwenshuju".getBytes(), new byte[12], new byte[2]);
        System.out.println("密文: " + Forms.byteToHexString(bytes.get(0)));
        System.out.println("tag: " + Forms.byteToHexString(bytes.get(1)));

        byte[] bytes1 = api.proKeyDecData(sm4Key, TACryptConst.KEY_ALG_SM4, sm4CV, Forms.hexStringToByte("C0C64CD82E3B2DC8C8F4****F5BA4F0BCF7AC04E08E8"), b, Forms.hexStringToByte("75F2C068A5****F0BCF7AC04E08E8"), TACryptConst.ENC_MODE_CBC,
                b, new byte[0], new byte[0], TACryptConst.KEY_ALG_AES256, 1, 3, new byte[16], TACryptConst.KEY_ALG_SM4, TACryptConst.ENC_MODE_GCM,
                bytes.get(0), new byte[12], new byte[2], bytes.get(1));

        System.out.println("解密后的数据明文:" + new String(bytes1));
    }

    byte[] srcRSACipher = Forms.hexStringToByte("83E265207D4566C7704DF9E6170181378CA028FB********508F919F4C0B3F2F7C0B79E661001B79FB0F0205A97CECFBE25DC4C711EA");

    byte[] srcRSACipherMAC = Forms.hexStringToByte("948D994479****72E54468349B3E5");

    byte[] srcRSACipherTag = Forms.hexStringToByte("9C8A7CB4C6****75F0681ED497EDF");

    byte[] srcRSApublicKey = Forms.hexStringToByteArray("308186028180E14CAAFFCEC6D014457D7CA3E943********BE8B795E10474954FE01BAAC63532520069465FA62EDB266AADEBB020103");
    /**
     * RSA LMK加密的私钥
     */
    byte[] srcRSAprivateKey = Forms.hexStringToByteArray("000202703D0652C7027B7D94B45A896646A9DC7C********571BC7CE29B67920538D509C58B1D8F966AF7E5321CDB2386164844D2BCB");


    byte[] srcSM2Cipher = Forms.hexStringToByte("83E260209C09CEF21E1A****0B8D670537112DFB030F");

    byte[] srcSM2CipherMAC = Forms.hexStringToByte("7DF725131F****F029550F2F073E9");

    byte[] srcSM2CipherTag = Forms.hexStringToByte("A2181C5822****E37C072987D1B7E");

    byte[] srcSM2publicKey = Forms.hexStringToByteArray("3059301306072A8648CE3D020106082A811CCF55********F8D3F9E5A31C7DE80940637E036B2D6FD36A0F586D4CDC3A610A269E89");

    byte[] srcSM2privateKey = Forms.hexStringToByteArray("79E62264C314D1D3279D****F2BC777F8CBE7EC55699");


    /**
     * 大数据包加解密
     */
    @Test
    public void bigDataEnc() throws TAException {
        byte[] enc = api.bigDataEnc(Forms.hexStringToByteArray("6DF7292D86****81F7C94DDC967A0"), "AES/ECB/PKCS5Padding", "demaxiyazhili".getBytes(), new byte[0]);
        System.out.println(Forms.byteToHexString(enc));
        byte[] dec = api.bigDataDec(Forms.hexStringToByteArray("6DF7292D86****81F7C94DDC967A0"), "AES/ECB/PKCS5Padding", enc, new byte[0]);
        System.out.println(new String(dec));

    }

    /**
     * 计算MAC、校验Mac
     */
    @Test
    public void mac() throws TAException {
        byte[] bytes = api.calMac(1, 0, 2, sm4Key, 7, "1111111111111111".getBytes(),
                new byte[16]);
        System.out.println("计算MAC结果:" + Forms.byteToHexString(bytes));
        boolean b = api.verifyMAC(1, 0, 2, sm4Key, 7, "1111111111111111".getBytes(),
                new byte[16], bytes);
        System.out.println("校验MAC结果:" + b);
    }

    /**
     * 计算HMAC
     */
    @Test
    public void hmac() throws TAException {
        ArrayList<byte[]> hmac = api.hmac(20, 0, 2, sm4Key, new byte[0], "shuyaojisuandeshuju".getBytes());
        for (int i = 0; i < hmac.size(); i++) {
            System.out.println(Forms.byteToHexString(hmac.get(i)));
        }
    }

    /**
     * 产生RSA算法密钥对,私钥由LMK加密输出
     */
    @Test
    public void generateRSAKeyPair() throws TAException, IOException {
        ArrayList<byte[]> bytes = api.genRSAKey(2048, 65537);

        System.out.println("DER编码的公钥:" + Forms.byteToHexString(bytes.get(0)));
        System.out.println("LMK加密的私钥:" + Forms.byteToHexString(bytes.get(1)));
    }


    /**
     * 产生RSA密钥对,保护密钥加密输出
     */
    @Test
    public void protectionKeyRSA() throws TAException, IOException {
        ArrayList<byte[]> bytes = api.proGenRSAKey (sm4Key, TACryptConst.KEY_ALG_SM4, sm4CV, 2048, 3,
                b, TACryptConst.ENC_MODE_ECB, b, new byte[2]);
        System.out.println("DER编码的公钥:" + Forms.byteToHexString(bytes.get(0)));
        System.out.println("LMK加密的私钥:" + Forms.byteToHexString(bytes.get(1)));
        System.out.println("保护密钥加密私钥的密文:" + Forms.byteToHexString(bytes.get(2)));
        System.out.println("非对称私钥MAC的长度:" + Forms.byteToHexString(bytes.get(3)));
    }

    /**
     * RSA 私钥签名 验签
     */
    byte[] privateRSA = Forms.hexStringToByte("000204B07672172F114E8E847A5FB9EC3DD32CD1********AE837EB0B233D98470234F3EAD29C2DAB368CF5463151BCB266DEF496D8E");
    byte[] publicRSA = Forms.hexStringToByte("3082010902820100EED2CF3C2E3624D65718E0F1********556D927F5DA9529C22D5C701B8B1BB7836D351A815A69116110203010001");
    byte[] publicR77 = Forms.hexStringToByte("3082010A0282010100A636C484374F9F039EB431********FE2D80A275BF5D096D2E07BA9ED5A75A10D425B03B84BB57990203010001");
    @Test
    public void RSApriSign() throws TAException, IOException {
        byte[] bytes = api.RSAPriKeySign(privateRSA,TACryptConst.PADDING_MODE_NO, 4, 0,
                0, 0, Forms.hexStringToByte("9ECA5459BA0B5CA0****55E9DC2B6FFA85CE"));
        System.out.println("签名结果:" + Forms.byteToHexString(bytes));
        boolean b = api.RSAPubVerify(publicRSA,TACryptConst.PADDING_MODE_PKCS15, TACryptConst.DIGEST_ALG_SHA256, 0,
                0, 0, bytes, Forms.hexStringToByte("9ECA5459BA0B5CA0****55E9DC2B6FFA85CE"));
        System.out.println("验签结果:" + b);
//        ArrayList<byte[]> bytes1 = RasKeyUtils.loadDerRsaPublicKey(publicR77);
//        for (int i = 0; i < bytes1.size(); i++) {
//            System.out.println(Forms.byteToHexString(bytes1.get(i)));
//        }
//
//        byte[] bytes = api.RSAPriKeySign(77,TACryptConst.PADDING_MODE_PSS, TACryptConst.DIGEST_ALG_SHA256, TACryptConst.MGF,
//                TACryptConst.DIGEST_ALG_SHA256, 10, "1234567890".getBytes());
//        System.out.println("签名结果:" + Forms.byteToHexString(bytes));
//        boolean b = api.RSAPubVerify(publicR77,TACryptConst.PADDING_MODE_PSS, TACryptConst.DIGEST_ALG_SHA256, TACryptConst.MGF,
//                TACryptConst.DIGEST_ALG_SHA256, 10, bytes, "1234567890".getBytes());
//        System.out.println("验签结果:" + b);
    }

    /**
     * RSA加解密运算
     */
    @Test
    public void RSAencdata() throws TAException {
        byte[] bytes = api.RSAPubEncData(11, 1, TACryptConst.DIGEST_ALG_SHA256, new byte[0], Forms.hexStringToByte("{createTime=1606380202000, createUserId=144, ip=124.204.XX.XX, key=SYJHD202011266020179058, orderNumber=SYJHD202011266020179058, productId=161391, scene=SYJHD}"));
        System.out.println("公钥加密结果:" + Forms.byteToHexString(bytes));
        byte[] bytes1 = api.RSAPriDecData(11, 1, TACryptConst.DIGEST_ALG_SHA256,new byte[0], bytes);
        System.out.println("私钥解密结果:" + Forms.byteToHexString(bytes1));
    }

    /**
     * RSA私钥解密,私钥受保护密钥保护
     */
    @Test
    public void priDecryptRSA() throws TAException {
        byte[] bytes = api.proRSAPriKeyDec (sm4Key, TACryptConst.KEY_ALG_SM4 , sm4CV, srcRSACipher, b, srcRSACipherMAC, TACryptConst.DIGEST_ALG_SHA256,
                b, new byte[2], srcRSACipherTag, 2, TACryptConst.MGF, TACryptConst.DIGEST_ALG_SHA256,new byte[0], Forms.hexStringToByteArray("BFA03DB9BD0A4DE4809B59B04BF663E8E541B0CF********5FD9E0A80116771AC436ED1EDE46CF272FD1DD4D3A5174D2D178D9A21F3D"));
        System.out.println("解密后的明文数据:" + Forms.byteToHexString(bytes));
    }

    /**
     * RSA私钥签名,私钥受保护密钥保护
     */
    @Test
    public void privateSignRSA() throws TAException, IOException {
        byte[] bytes = api.proRSAPriKeyDecSign(sm4Key, TACryptConst.KEY_ALG_SM4, sm4CV, srcRSACipher, b, srcRSACipherMAC, TACryptConst.DIGEST_ALG_SHA256,
                b, new byte[2], srcRSACipherTag, TACryptConst.DIGEST_ALG_SHA256, "1234567890".getBytes(), TACryptConst.PADDING_MODE_PSS, TACryptConst.MGF, TACryptConst.DIGEST_ALG_SHA256, 10);

        System.out.println("签名结果:" + Forms.byteToHexString(bytes));
        boolean b = api.RSAPubVerify(srcRSApublicKey,TACryptConst.PADDING_MODE_PSS, TACryptConst.DIGEST_ALG_SHA256, TACryptConst.MGF, TACryptConst.DIGEST_ALG_SHA256, 10, bytes, "1234567890".getBytes());
        System.out.println("验签结果:" + b);
    }

    /**
     * RSA非对称密钥转加密,由保护密钥1转为保护密钥2加密
     */
    @Test
    public void RSAConversionEncryption() throws TAException {
        ArrayList<byte[]> bytes = api.conversionEncryption(0, TACryptConst.KEY_ALG_SM4, sm4Key, sm4CV, TACryptConst.KEY_TYPE_RSA,
                -1, srcRSACipher, b, srcRSACipherMAC, TACryptConst.ENC_MODE_GCM, b, new byte[2], srcRSACipherTag,
                0,
                TACryptConst.KEY_ALG_SM4, sm4Key2, sm4Key2CV, b, TACryptConst.ENC_MODE_ECB, b, new byte[2]);
        for (int i = 0; i < bytes.size(); i++) {
            System.out.println("第" + i + "个===" + Forms.byteToHexString(bytes.get(i)));
        }
    }

    /**
     * RSA非对称密钥保护导入对称密钥
     */
    @Test
    public void tets1() throws TAException {
        ArrayList<byte[]> bytes = api.RSAProImplSymm(srcRSAprivateKey, 2, TACryptConst.DIGEST_ALG_SHA256, new byte[10], 200,
                TACryptConst.KEY_ALG_SM4, Forms.hexStringToByteArray("5C59EBCD0A48E51038853E490C76AD83122964E3********AD4FCF0A1D20DC5A0AAB878DADC04903CCE5B3D06219FDB4497905FBEA9E"), "916-zjl".getBytes());
        System.out.println("LMK加密的对称密钥:" + Forms.byteToHexString(bytes.get(0)));
        System.out.println("对称密钥的校验值:" + Forms.byteToHexString(bytes.get(1)));
    }

    /* ***************************************************************************************************** */

    /**
     * 产生SM2/ECC密钥对,保护密钥加密输出
     */
    @Test
    public void generateProtectionKeySM2() throws TAException {
        ArrayList<byte[]> bytes = api.proGenSM2OrECCKey (sm4Key, TACryptConst.KEY_ALG_SM4, sm4CV, 0x0007,
                b, TACryptConst.ENC_MODE_GCM, b, new byte[16]);
        System.out.println("DER编码的公钥:" + Forms.byteToHexString(bytes.get(0)));
        System.out.println("LMK加密的私钥:" + Forms.byteToHexString(bytes.get(1)));
        System.out.println("保护密钥加密私钥的密文:" + Forms.byteToHexString(bytes.get(2)));
        System.out.println("非对称私钥MAC:" + Forms.byteToHexString(bytes.get(3)));
        System.out.println("tags:" + Forms.byteToHexString(bytes.get(4)));

    }

    /**
     * 产生SM2算法密钥对,私钥由LMK加密输出
     */
    @Test
    public void generateSM2Key() throws TAException {
        ArrayList<byte[]> bytes = api.genSM2Key();
        System.out.println("DER编码的公钥:" + Forms.byteToHexString(bytes.get(0)));
        System.out.println("LMK加密的私钥:" + Forms.byteToHexString(bytes.get(1)));
    }

    /**
     * 产生ECC算法密钥对,私钥由LMK加密输出
     */
    @Test
    public void generateECCKey() throws TAException {
        ArrayList<byte[]> bytes = api.genECCKey(0x0007);
        System.out.println("DER编码的公钥:" + Forms.byteToHexString(bytes.get(0)));
        System.out.println("LMK加密的私钥:" + Forms.byteToHexString(bytes.get(1)));
 
    }

    byte[] data = Forms.hexStringToByte("20D90A83A4654FB8****0371B374F76DEFA5");

    /**
     * ECC 签名验签
     */
    @Test
    public void ECCPrivateKeySign() throws TAException {

        byte[] bytes = api.priKeySign(0x0007, Forms.hexStringToByteArray("61971383CD4D760CF77C****4C1C935F18B4CCCFBF3A"), data);
        System.out.println("ECC签名结果:" + Forms.byteToHexString(bytes));

        boolean b = api.pubKeyVerify(0x0007, Forms.hexStringToByteArray("3059301306072A8648CE3D020106082A811CCF55********1ACA51CB99CD452FA11B5B6BBB4AA31C2DBCC696FC57C8F9F8F01948FE"), data, bytes);
        System.out.println("ECC验签结果:" + b);
    }

    /**
     * SM2 签名 验签
     */
    @Test
    public void TestSm2() throws TAException {
        byte[] bytes = api.priKeySign(0x0007, privateKeySM2, sm3);
        System.out.println("签名结果:" + Forms.byteToHexString(bytes));
        boolean b = api.pubKeyVerify(0x0007, privateKeySM2DER, sm3, bytes);
        System.out.println("验签结果:" +  b);
    }


    @Test
    public void SM2Sign() throws TAException {
        byte[] baInData = "2222222222222222".getBytes();
        //7.计算SM3摘要
        System.out.println("数据摘要:SM3");
        String sAlg = "SM3";
        byte[] baUserId = new byte[0];
        byte[] baPubKey = Forms.hexStringToByteArray("3059301306072A8648CE3D020106082A811CCF55********9A1AD40BEEE37267F8F1F97E67BCE29A4E1CCAB0979A1E85F81010E042");
        byte[] baHashInitRes = api.HashInit(sAlg, baUserId, baPubKey);
        byte[] baHashUpdateRes = api.HashUpdate(baHashInitRes, baInData);
        byte[] baHashSm3 = api.HashFinalize(baHashUpdateRes);
        System.out.println(String.format("数据摘要: %s", Forms.byteToHexString(baHashSm3)));


        //8.非对称密钥签名验签
        System.out.println("数据非对称签名验签:SM2");

        int iCurveId = 0x0007;
        System.out.println(String.format("数据原文(哈希值): %s", Forms.byteToHexString(baHashSm3)));

        byte[] baSignatureSm2 = api.priKeySign(iCurveId, 2, baHashSm3);
        System.out.println(String.format("数据签名: %s", Forms.byteToHexString(baSignatureSm2)));
        boolean blVerifyResSm2 = api.pubKeyVerify(iCurveId, baPubKey, baHashSm3, baSignatureSm2);
        System.out.println(blVerifyResSm2);
    }


    byte[] sm2 = Forms.hexStringToByte("3059301306072A8648CE3D020106082A811CCF55********55A4C790CDE94A1B179CC12A39A856755F6677E87905BD903987425AF3");

    byte[] sm2PrivateKey = Forms.hexStringToByte("4F23C664B68C8A38B31F****66976CEA234A749F031D");

    /**
     * SM2加密解密运算
     */
    @Test
    public void TestSM2EncAndDec() throws TAException {
        byte[] bytes = api.SM2PubKeyEnc(888, Forms.hexStringToByte("1111111111****111111111111111"));
        System.out.println("加密结果:" + Forms.byteToHexString(bytes));

        byte[] bytes1 = api.SM2PriKeyDec(888, bytes);
        System.out.println("解密结果:" + Forms.byteToHexString(bytes1));
    }



    byte[] sm2Key = Forms.hexStringToByte("3059301306072A8648CE3D020106082A811CCF55********55A4C790CDE94A1B179CC12A39A856755F6677E87905BD903987425AF3");
    byte[] sm2Cipher = Forms.hexStringToByte("83E260209C09CC3F0103****FD8880E68AC28BFFF0F3");
    byte[] sm2CipherMAC = Forms.hexStringToByte("8184BE3669****B673814E59E7700");
    byte[] sm2CipherTag = Forms.hexStringToByte("8FD638CA4D****213F5777253D192");
    byte[] sm2PriKey = Forms.hexStringToByte("4F23C664B68C8A38B31F****66976CEA234A749F031D");


    /**
     * ECC/SM2私钥解密,私钥受保护密钥保护
     */
    @Test
    public void protectionPrivateKeyDecrypt() throws TAException {
        byte[] bytes = api.proPriKeyDec(sm4Key, TACryptConst.KEY_ALG_SM4, sm4CV, sm2Cipher, b, sm2CipherMAC, TACryptConst.ENC_MODE_GCM,
                b, new byte[2], sm2CipherTag, Forms.hexStringToByteArray("E9C17D82604F992BB3AB8FE0F766441DACC05EB7********32FACEC8316B880499E6E70260333E9F29CEBCF3F8E10C151F79445276F6"));
        System.out.println("解密后的数据明文:" + Forms.byteToHexString(bytes));
    }

    /**
     * ECC/SM2私钥签名,私钥受保护密钥保护
     */
    @Test
    public void privateSignSM2() throws TAException {
        byte[] bytes = api.proPriKeySign(sm4Key,TACryptConst.KEY_ALG_SM4 , sm4CV, sm2Cipher, b, sm2CipherMAC, TACryptConst.ENC_MODE_GCM,
                b, new byte[2], sm2CipherTag, Forms.hexStringToByteArray("20D90A83A4654FB8****0371B374F76DEFA5"));
        System.out.println("ECC/SM2私钥签名结果(私钥受保护密钥保护):" + Forms.byteToHexString(bytes));

        boolean b = api.pubKeyVerify(7, sm2Key, Forms.hexStringToByteArray("20D90A83A4654FB8****0371B374F76DEFA5"), bytes);
        System.out.println("ECC/SM2公钥验签结果(私钥受保护密钥保护)" + b);
    }

    /**
     * SM2非对称密钥保护导入对称密钥
     */
    @Test
    public void SM2ImplKEK() throws TAException {
        ArrayList<byte[]> bytes = api.SM2ImplKEK(sm2PriKey, 300, TACryptConst.KEY_ALG_SM4, Forms.hexStringToByteArray("9A9161F87BCBD3E9BC8866B8706E8F75B682DA27********13440F2DAD9AE786E3D73349D78FA7915B3CB633EFD9A88E638D93297934"), "914-zjl".getBytes());
        System.out.println("LMK加密的对称密钥:" + Forms.byteToHexString(bytes.get(0)));
        System.out.println("对称密钥的校验值:" + Forms.byteToHexString(bytes.get(1)));
    }

    /**
     * SM2/ECC非对称转加密
     */
    @Test
    public void conversionEncryption() throws TAException {
        ArrayList<byte[]> bytes = api.conversionEncryption(0, TACryptConst.KEY_ALG_SM4, sm4Key, sm4CV, 2,
                -1, sm2Cipher, b, sm2CipherMAC, TACryptConst.ENC_MODE_GCM, b, new byte[2], sm2CipherTag, 0,
                TACryptConst.KEY_ALG_SM4, sm4Key2, sm4Key2CV, b, TACryptConst.ENC_MODE_GCM, b, new byte[2]);
        for (int i = 0; i < bytes.size(); i++) {
            System.out.println("第" + i + "个===" + Forms.byteToHexString(bytes.get(i)));
        }
    }

    /**
     * 摘要运算,填充摘要数据
     */
    @Test
    public void testGenHash() throws TAException {
        byte[] hash = genHash();
        System.out.println("摘要结果:" + Forms.byteToHexString(hash));

        // 计算校验正确摘要结果
        String string = "704423DF78242B08E821F7F8FA05A5325AA1BD842BE4EB9827C765DFFF434C1A";

        byte[] bytes3 = genHash();
        System.out.println("验证结果:" + Arrays.equals(Forms.hexStringToByteArray(string),bytes3));

        String wrongHash = "669523DF78242B08E821F7F8FA05A5325AA1KD842BE4EB9827C765DFFF434C1A";

        System.out.println("错误验证结果:" + Arrays.equals(Forms.hexStringToByteArray(wrongHash),bytes3));
    }
    public byte[] genHash() throws TAException {
        byte[] bytes2 = api.HashInit("SM3", new byte[0], privateKeySM2DER);
        byte[] bytes = api.HashUpdate(bytes2, Forms.hexStringToByteArray("1234567890"));
        byte[] bytes1 = api.HashFinalize(bytes);
        return bytes1;
    }


    /**
     * 产生随机数
     */
    @Test
    public void genRandom() throws TAException {
        String s = api.genRandom(15);
        System.out.println(s);
    }

    /**
     * 获取加密机状态
     */
    @Test
    public void getHSMstatus() throws TAException {
        String hsMstatus = api.getHSMstatus();
        System.out.println(hsMstatus);
    }

    /**
     * lmk to kek
     * @throws TAException
     */
    @Test
    public void test3() throws TAException {
        ArrayList<byte[]> bytes = api.LMKToKEK(TACryptConst.KEY_ALG_SM4, TACryptConst.ENC_MODE_GCM, b,
                new byte[2], 0, sm4Key,
                new byte[0], new byte[0], 5, 0,
                1, 0, TACryptConst.KEY_ALG_SM4,
                sm4Key2, new byte[16]);
        System.out.println("使用保护密钥加密密钥密文:" + Forms.byteToHexString(bytes.get(0)));
        System.out.println("当选择产生MAC时,输出MAC:" + Forms.byteToHexString(bytes.get(1)));
        System.out.println("tags:" + Forms.byteToHexString(bytes.get(2)));
        System.out.println("密钥校验值:" + Forms.byteToHexString(bytes.get(3)));
    }

    /**
     * 其他密钥加密转LMK加密
     * @throws TAException
     */
    @Test
    public void otherEncKeyToLMLEncKey() throws TAException {
        ArrayList<byte[]> bytes = api.otherEncKeyToLMLEncKey(0, 7, 6,
                Forms.hexStringToByteArray("00000000000000000000000000000000"),
                Forms.hexStringToByteArray("00000000000000000000000000000000"),
                Forms.hexStringToByteArray("71802E75BD****996A9B9DA6616E9"),
                0,  Forms.hexStringToByteArray("B36847D6E8****4EEB65558A2626C"),
                new byte[0], new byte[0], 5, -1,-1, new byte[0], 0, 7,
                Forms.hexStringToByte("9940568000****9C7F45977D291AA"));
        System.out.println("=============保护密钥为对称密钥============");
        for (int i = 0; i < bytes.size(); i++) {
            System.out.println(Forms.byteToHexString(bytes.get(i)));
        }

        ArrayList<byte[]> bytes2 = api.otherEncKeyToLMLEncKey(2, -1, -1,
                new byte[0], new byte[0], new byte[0],
                888,  new byte[0], new byte[0],
                new byte[0], 1,
                1, 1, new byte[0], 0, 7,
                Forms.hexStringToByte("7C78EAFE26890D48096AB8141B1D5890BF1921DD********5329ADED546F44C52C8F49EAC46647650D9B983224E9E005CFCAA88B019D"));

        System.out.println("=============保护密钥为ECC密钥============");
        for (int i = 0; i < bytes2.size(); i++) {
            System.out.println(Forms.byteToHexString(bytes2.get(i)));
        }
        ArrayList<byte[]> bytes1 = api.otherEncKeyToLMLEncKey(1, -1, -1,
                new byte[0], new byte[0], new byte[0],
                11,  new byte[0], new byte[0], new byte[0], 3,
                1, 1, new byte[0], 0, 7,
                Forms.hexStringToByte("6149EE02F14EE6420BC2B462003CCCE2413CE491********E2CE400522E06DCBAB44213A85B668764EC33EE71D372F5A904252A539AA"));

        System.out.println("=============保护密钥为RSA密钥============");
        for (int i = 0; i < bytes1.size(); i++) {
            System.out.println(Forms.byteToHexString(bytes1.get(i)));
        }

    }
    @Test
    public void enveopEncAndDec() throws TAException {
        byte[] bytes = api.enveopEnc(sm2Key, "1111111111111111".getBytes());
        System.out.println("数字信封封装结果:" + Forms.byteToHexString(bytes));
        byte[] bytes1 = api.enveopDec(sm2PriKey, bytes);
        System.out.println("数字信封拆封结果:" + new String(bytes1));
    }

    /**
     * 对称密钥转加密 & 非对称转加密
     */
    @Test
    public void symmetryConversionEncryptionAES256() throws TAException {
        ArrayList<byte[]> bytes = api.conversionEncryption(0, TACryptConst.KEY_ALG_AES256,
                Forms.hexStringToByteArray("5BD90CDDBC8645B4****96B6E52CC003D04F"),
                Forms.hexStringToByteArray("F8B6****4FD3"),
                TACryptConst.KEY_TYPE_SYMMETRY,
                TACryptConst.KEY_ALG_AES256,
                Forms.hexStringToByteArray("CFE8E3D44F753D3F****88EF70B54E65E232"), b,
                Forms.hexStringToByteArray("8F2440B220****7D8D807A832A19F"), TACryptConst.ENC_MODE_GCM, b, new byte[22],
                Forms.hexStringToByteArray("B5294D5910****80774B61BA48FA4"),
                0,
                TACryptConst.KEY_ALG_SM4, sm4Key2, sm4Key2CV, b, TACryptConst.ENC_MODE_CBC, b, new byte[12]);
        for (int i = 0; i < bytes.size(); i++) {
            System.out.println("第" + i + "个===" + Forms.byteToHexString(bytes.get(i)));
        }
    }

    /**
     * 对称密钥转加密 & 非对称转加密
     */
    @Test
    public void symmetryConversionEncryption() throws TAException {
        ArrayList<byte[]> bytes = api.conversionEncryption(0, TACryptConst.KEY_ALG_SM4,
                Forms.hexStringToByteArray("CBDCCE3378****E0B3BAA46CF3557"),
                Forms.hexStringToByteArray("F668****C2AD"),
                0,TACryptConst.KEY_ALG_SM4,
                Forms.hexStringToByteArray("6BFC84C39C****6C7FA2A30C912A1"), b,
                Forms.hexStringToByteArray("AB75C62580****39327B45881F589"), TACryptConst.ENC_MODE_GCM,
                b, new byte[0], Forms.hexStringToByteArray("4A501743FA****4A0A8705192C1C8"),0,
                TACryptConst.KEY_ALG_SM4,
                Forms.hexStringToByteArray("CBDCCE3378****E0B3BAA46CF3557"),
                Forms.hexStringToByteArray("F668****C2AD"), b, TACryptConst.ENC_MODE_GCM, b, new byte[0]);
        for (int i = 0; i < bytes.size(); i++) {
            System.out.println("第" + i + "个===" + Forms.byteToHexString(bytes.get(i)));
        }
    }

    /**
     * 对称密钥转加密 & 非对称转加密
     */
    @Test
    public void symmetryConversionEncryption1() throws TAException {
        ArrayList<byte[]> bytes = api.conversionEncryption(0, TACryptConst.KEY_ALG_SM4, sm4Key, sm4CV,
                TACryptConst.KEY_TYPE_ECC_OR_SM2,
                TACryptConst.KEY_ALG_SM4,
                Forms.hexStringToByteArray("83E260209C09CC3FEFDE****27A17AEB2C8919E1E4CF"), b,
                Forms.hexStringToByteArray("E60EFC4882****F68D0EB622298FB"),
                TACryptConst.ENC_MODE_GCM, b, new byte[16],
                Forms.hexStringToByteArray("B200ED220D****C4438649057EB02"),
                0,
                TACryptConst.KEY_ALG_SM4, sm4Key, sm4CV, b, TACryptConst.ENC_MODE_GCM, b, new byte[16]);
        for (int i = 0; i < bytes.size(); i++) {
            System.out.println("第" + i + "个===" + Forms.byteToHexString(bytes.get(i)));
        }
    }


    /**
     * 对称算法 CMK 保护导入非对称CMK
     */
    @Test
    public void importCMKByCMK() throws TAException {
        ArrayList<byte[]> bytes = api.importCMKByCMK("zjlimpl".getBytes(), 7,
                6,  //保护CMK DomainKey 加密 CMK 使用算法模式标识
                new byte[16],     //ECB 模式解密时使用的 IV 数据
                new byte[16],      //GCM 模式解密时的认证数据
                Forms.hexStringToByteArray("566F7CE9E5****F02D7A7667E3F7C"), //GCM 模式解密时的 MAC 值
                Forms.hexStringToByteArray("DA23B170CE****772B3F2AE2CCA97"),//密钥密文
                Forms.hexStringToByteArray("7192C7C6F1****FE8A51BA9256C87"),  //GCM tags
                6, //保护密钥加密模式
                new byte[16],//保护密钥IV
                new byte[16], //认证数据AAD
                Forms.hexStringToByteArray("8DE9DFEE4B****1C08A38BDD8A92F"), //tags
                5,//保护密钥加密填充方式
                12, //会话密钥类型
                7,  //会话CMK 非对称密钥的算法标识
                Forms.hexStringToByteArray("420B9FE23A2B162F3C4574919E9EBD44040F7C53********0B18990EF5C6F3A93AB80B41458311EA9F9A1890752427E24F5062AD4A"),//会话私钥密文数据
                "32-1".getBytes(),//会话DomainKey 标签
                6,//会话DomainKey 加密 CMK 使用算法模式标识
                new byte[16],//会话加密上下文(非 ECB 模式加密时使用的 IV 数据)
                new byte[16]//会话认证上下文数据(GCM 模式加密时的认证数据)
        );
        System.out.println("使用保护密钥加密密钥密文:" + Forms.byteToHexString(bytes.get(0)));
        System.out.println("MAC:" + Forms.byteToHexString(bytes.get(1)));
        System.out.println("tags:" + Forms.byteToHexString(bytes.get(2)));
        System.out.println("密钥校验值:" + Forms.byteToHexString(bytes.get(3)));
    }

    @Test
    public void testData() throws TAException {
        //产生对称密钥,保护密钥保护输出
        ArrayList<byte[]> bytes = api.proGenSymmKey(603,
                -1, null, TACryptConst.KEY_ALG_SM4, b,
                TACryptConst.ENC_MODE_GCM,b, b);
        System.out.println("LMK加密的会话密钥密文:" + Forms.byteToHexString(bytes.get(0)));
        System.out.println("会话密钥的校验值:" + Forms.byteToHexString(bytes.get(1)));
        System.out.println("保护密钥加密的会话密钥密文:" + Forms.byteToHexString(bytes.get(2)));
        System.out.println("会话密钥的MAC值:" + Forms.byteToHexString(bytes.get(3)));
        System.out.println("tags:" + Forms.byteToHexString(bytes.get(4)));
        System.out.println("-------------------------------------------------");
        //对称密钥(受保护密钥保护)加密数据
        ArrayList<byte[]> bytes1 = api.proKeyEncData(603, -1, null,
                bytes.get(2),
                b, bytes.get(3), TACryptConst.ENC_MODE_GCM,
                b, b, bytes.get(4),
                TACryptConst.KEY_ALG_SM4, 0, 0,
                new byte[16], TACryptConst.KEY_ALG_SM4, TACryptConst.ENC_MODE_GCM,
                Forms.hexStringToByteArray("0000000000000000000000000000000000000000********353F49C7164DAE6C691FC25CD494D9A28D0F6C4B51F3BB9DC85ADDBE09"), new byte[16], new byte[16]);
        System.out.println("密文: " + Forms.byteToHexString(bytes1.get(0)));
        System.out.println("tag: " + Forms.byteToHexString(bytes1.get(1)));
    }

    @Test
    public void agreementKey() throws TAException {
//        byte[] bytes = api.agreementKey(0x02CB, 4, 4, Forms.hexStringToByte("3076301006072A8648CE3D020106052B81040022********5645477442F9BF8BE9BF81EAD69CDA6C63FCF5244A383C57DDB62465E63B"));
//        System.out.println("secp384r1协商结果:" + Forms.byteToHexString(bytes));
//        byte[] bytes1 = api.agreementKey(0x0007, 3, 6, Forms.hexStringToByte("3059301306072A8648CE3D020106082A811CCF55********DF9A3DF50D67073CF246FC3406337B50E987F2AC3943D2FF5C7ECAD197"));
//        System.out.println("0x0007协商结果:" + Forms.byteToHexString(bytes1));
//        byte[] bytes2 = api.agreementKey(0x0007, 3, Forms.hexStringToByte("E59842CEEC68775E****F7DF23E08F7F6B8D"), Forms.hexStringToByte("3059301306072A8648CE3D020106082A811CCF55********B972EB19EA77A6AB74F345688B8458F1015885FCE435A4E3679DE0E34F"));
//        System.out.println("0x0007外部私钥明文协商结果:" + Forms.byteToHexString(bytes2));
//        byte[] bytes3 = api.agreementKey(0x039B, 0, 5, Forms.hexStringToByte("304A301406072A8648CE3D020106092B24030302********868F7D34BABEEB5A20F7DF5543091DD740DD3780B5EBEF631615571ADC"));
//        System.out.println("0x039B协商结果:" + Forms.byteToHexString(bytes3));
        byte[] bytesA = api.agreementKey(0x019F, 3, 13, Forms.hexStringToByte("3059301306072A8648CE3D020106082A8648CE3D********7558F1DA9AC8CDF5E7FA72C9931FA90EE06B3CE07E13A7845A05BA7C73"));
        System.out.println(bytesA.length);
        System.out.println("0x0007协商结果:" + Forms.byteToHexString(bytesA));
        byte[] bytesB = api.agreementKey(0x019F, 3, 15, Forms.hexStringToByte("3059301306072A8648CE3D020106082A8648CE3D********C7AB0964E53872FBF0511FF6E7661CF94B7D82C8BF78D211B1FA73F271"));
        System.out.println("0x0007协商结果:" + Forms.byteToHexString(bytesB));

    }

    /**
     * 根据密钥索引获取对称密钥详情
     */
    @Test
    public void getKeyInfo() throws TAException {
        String[] keyInfo = api.getKeyInfo(66);
        System.out.println(keyInfo[0]);
    }
    /**
     * 根据密钥索引获取RSA公钥
     */
    @Test
    public void exportRSAPublicKey() throws TAException, IOException {
        ArrayList<byte[]> keyInfo = api.exportRSAPublicKey(77,0);
        System.out.println(Forms.byteToHexString(keyInfo.get(0)));
    }
    /**
     * 根据密钥索引获取ECC公钥
     */
    @Test
    public void ExportEncPublicKey() throws TAException {
        byte[] keyInfo = api.exportECCPublicKey(66,0);
        System.out.println(Forms.byteToHexString(keyInfo));
    }

    @Test
    public void generateAndSaveKey() throws Exception {
        ArrayList<byte[]> symmKey = api.generateSymmKey(7, 32);
        for (int i = 0; i < symmKey.size(); i++) {
            System.out.println(Forms.byteToHexString(symmKey.get(i)));
        }
        boolean b = api.generateRSAKey(2048, 65537, 13);
        System.out.println("产生并保存RSA密钥对" + (b ? "成功":"失败"));
        boolean b1 = api.generateECCKey(0x019F, 8);
        System.out.println("产生并保存ECC密钥对" + (b1 ? "成功":"失败"));

    }


}