在生产环境使用加密服务

重要

本文中含有需要您注意的重要提示信息,忽略该信息可能对您的业务造成影响,请务必仔细阅读。

本文指导您在生产环境中如何快速上手使用加密服务。

注意事项

为了保证加密服务的高可用性,建议您至少购买2个不同可用区的密码机实例,其中一个为主密码机,一个为子密码机。

前提条件

  • 已购买并启用密码机实例。具体操作,请参见购买并启用密码机实例

    警告

    为了保证密码机实例数据的安全,请不要在实际生产环境中使用测试密钥。

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

    说明

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

步骤一:创建并激活集群

一个集群中包括一个主密码机实例与若干个非主密码机实例。集群内一个可用区的密码机实例使用同一子网。您可以通过同步集群的操作,将主密码机实例的数据、状态同步到其他非主密码机实例,包括但不限于密钥、应用许可。

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

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

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

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

    初始化方式

    操作步骤

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

    重要

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

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

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

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

    使用密码机实例管理工具初始化

    重要

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

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

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

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

    如果需要更多的密码机实例,您需要购买密码机实例,并添加密码机实例到集群。

步骤二:同步集群数据

主密码机数据变更后,您需要同步集群的数据到子密码机,实现实例数据的高可用性。当您第一次创建并激活集群后,您需要将集群的主密码机数据手动同步到集群的子密码机实例。当您扩展集群时,集群数据会自动同步到新添加的密码机实例。

警告

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

  1. 实例列表页面,找到目标主密码机实例,在操作列单击同步集群

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

(可选)步骤三:扩展集群

您可以将处于不同可用区的密码机实例加入到同一集群进行统一管理,提高加密服务的高可用性。添加到集群的密码机实例需符合以下要求:

  • 密码机实例未初始化。

  • 密码机实例为已启用未启用状态。

  • 密码机实例与主密码机为同一类型密码机。

  • 密码机实例未配置交换机或与主密码机属于同一交换机。

重要

如果密码机实例已配置了密码机实例白名单,加入集群后该密码机实例的访问白名单将继承集群的访问白名单,原密码机实例白名单将被清空。

  1. 实例列表页面,定位到目标主密码机实例,单击操作列的扩展集群

  2. 通过以下方式添加密码机实例到集群。

    • 还未购买密码机实例时,在添加密码机实例到集群 对话框,单击订购密码机,新购密码机实例。

      购买的密码机实例会自动添加到集群,同时加密服务会自动为该密码机实例分配IP地址,并完成集群内数据的同步。

    • 已购买密码机实例时,在添加密码机实例到集群 对话框,选择需要添加的密码机实例,单击添加,然后单击确定

步骤四:使用密码机实例

在密码机软件包中找到密码机的开发手册、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("669C1CEDDAFA267CC5D727EA727558B5");
    byte[] verifyValue = Forms.hexStringToByteArray("BD8596C22E5A4D88");

    byte[] symmetricKey1 = Forms.hexStringToByteArray("93EF12C95813586FEC3EFDBC7B37642D");
    byte[] verifyValue1 = Forms.hexStringToByteArray("78306FD68851B8E6");
    /**
     * LMK加密的会话密钥密文
     */
    byte[] symmetricKeyKEK = Forms.hexStringToByteArray("2E80A42018F186BCCBCF639F644629E8");
    /**
     * 会话密钥的校验值
     */
    byte[] verifyValueMAC = Forms.hexStringToByteArray("734D092CD8C23E38");
    /**
     * 保护密钥保护的密文
     */
    byte[] protectionKey = Forms.hexStringToByteArray("2EACE685C5EB2638D1208742F3BE60CD44210B43C894A77C");
    /**
     * 保护密钥保护的密文的MAC
     */
    byte[] protectionMAC = Forms.hexStringToByteArray("0CB8702D41CBE487");

    /**
     * RSA DER编码的公钥
     */
    byte[] publicKeyRSA = Forms.hexStringToByteArray("308186028180E14CAAFFCEC6D014457D7CA3E943DBABA1299BDBC17690C8E70F7BFA10EA02450805DA4C6CDC38BFBF1349C95B81A88177BA31C08E366EF965CA41EB36A2DACE611B80A752615A094B8291AAB6F8BB3A5894E72842371F34FA04C10DF42C2FEA95C51B9D49BE8B795E10474954FE01BAAC63532520069465FA62EDB266AADEBB020103");
    /**
     * RSA LMK加密的私钥
     */
    byte[] privateKeyRSA = Forms.hexStringToByteArray("000202703D0652C7027B7D94B45A896646A9DC7CA89825FB12121B3CC00E37BE933055D5C00E37BE933055D54718ADDAA677519BD9C054CA249B43888FE000B8AAC33BA87A2C326985704335EA54D7F171CABCAD5531B3ADF33255A24075EFFF62691D4375E6280A9442CA36AA46AC59FAB16D9A9A7A283440BB14BAB1E78DBE887AE93A2C94C547779190D3FA801379BA948537281EFEFE567FD963E5D6E5D442D908A68BB6E26F3776EA30B1136A3804844035E26308E9B44BE154E1D09382E5A72BD711A6936373A8C32B62AF88134690C30D8B5505004F3BA01D11D0D791C8FF53D0E0786ED192CF1105FCF82160921EEF23E7BD72F13587B316BD9A771CEABBD0186B45E09C86E718AD4E5444EFFE747FE0C39E85D6190F3347656E72F486C321D5EA0D42127149C99F4F799A31F91E5826B74FF720A6E3CC2BCBBF645DD3D4A6A7D0BC953B4CFEE4E0D2BABFD606292F9F2395464484C306FBD60E4DD293E5F56C60BF1482A05775F0EEBAFBF9B70841DDDCFC974DD4D87E54D6A6A7A1A585EF0F42B0763D5DD7B5ECA83AFE610C26C9EF559B7883AC4716240BDFDC91C6EA19A0C01BB9C053F2A9C7EBCAE7D0AA8FB0DB88EFCF9C50A134E04649DAFF21D724E5C3CC043DE950C2CF246392DC4CA592D28C5A959BEB80B304E3BD949AD33178C06209FE6EB7130A381DFFD80F916AE0E0DD8FFDD9C8C9895BC483993D6011754FAD3C9F83A59C31F47810F8B2B22E5F25EF13671DFF34ECB65DE71D5B13DC5880595BC60B18D4711AE4613C739E2A48B516F6233E9AA9834075CE58975907F06FBA3B85C97E2E90B60BFEF0F23527E770798B571BC7CE29B67920538D509C58B1D8F966AF7E5321CDB2386164844D2BCB");
    /**
     * RSA 保护密钥加密的私钥
     */
    byte[] privateKeyRSAKEK = Forms.hexStringToByteArray("6B2FB2BCC75604ABF5761FFA1027FF16324E3038B580C9F63AD3B57BD89059D5799974B4E5E9453763D94E682C629C4617C4E5393E9DDBFB0CFA2A4EA0E832F5C6A30F3EE63C327F6E044F3CB630D0C7DD96D93581835AA529797EB11CF3535650E431181717FDD1D7BBD9FB675FB027134BBF7F10F65245D9A82251A9171DAA439C175895904A2BB74F31BD94FF550023F6245C01DF83B2FCEDDF241307DDC831162AD2203BA3EBC4FD99EAE93C3208F16B0AAF85146ACE5FF06B11D7C81215708AA5C2651D380573F0EDA0984A73F5CE38E21541D50AACF5C5BCD42B6C94D064065ECAED4684E7A40C15904A73A801F2697AF6F3E32C3D7E156A1D1085CA32C7A002FA4AEAD439271E6E5904FC9AC3E65EEBAC51399F60DF3C61AF82BDA04D5E28B587382F8EB751096BC970B7A7DF26D997324F2D002D01A4C8F77C37BB65DBD1DED3B4545323DAE9489A08351507224574A2206FA7EAF8EF0A120D23D6B34E84645E95C3B58187BC91B8F6C04EF15075D6AF38B7E7DD77F6D2B8E66F11960C401BCE56BB4C157DAA26234678A37ACCFC7729CB5018449F7B6A23C0B16CA0B6A5FBE9FC7C8F9A3801A4159822DDDE8D9D7B7233CC3F77E7391DE720A2BFC69F6B938B565A28EBC6B4B665C553A9E1F32A17CC66CB8A2D7FE3EF6CB5112815D562F18EB34987B57DCFF064C7C24E97C3DCF3FD9BD50B351A2DD7CF03DA1F2DDA7A1BD2013C8339AFC4D22C135C49859C9C4CA4C9F730D2EE09A779D244C13FB5C3835F2FF04EE12537B01795D0ABE2D9695208542DC2FF8161AFD6F774E8D524B1DE6096530783");
    /**
     * RSA MAC
     */
    byte[] privateKeyRSAKEKMAC = Forms.hexStringToByteArray("701A4D3572D09760");

    /**
     * KEK 加密的RSA私钥
     */
    byte[] privateKeyKEK = Forms.hexStringToByteArray("7A833CC0FAFBA6EC063DF4827B8FD91FF4B9A69FB0C44FD972173C09E9E56F6918730269561A497403F9478D7BB64FE527F748AF86E3CE7C762A92A07D9C8BBCE0731F9F07C5889AE8B0FF7A31FCCCD76CD20A1AFB95B4D12BEA5DB84059B9CB1FB8F778989FD11CB7F8D84D812190F2EE0F479A4020FEB32C634528FBF660B3AD5AB0BA497B932902294C28B02807DC1AC28E8213BA39582AA677050F9E9256879935484B49D1CD115B39C0A41AE2B18263F78EA4CB781C931EA3C638097D1A7D4245C30ADA1B7C7793FD798EFAB86C3A91F573D4D2ECFA188588A31983320052901CC5AECAEDC5296506442546614B3DFDECA958B5E3A659EC8B52C5818E22F8E50C216264B560073F47E07B07E38CEF2DF4F6E4A458665FD31E6AA1C7B2FB5C4A15405C09E5F2B814FB260C1FFC560A2B6F3370C9DD96BA0A15BA72AB3622FE172F847D60383307C936246B977665CAB5E68EFA6E4EE1F9008FAE7A90D4A2A10AB70969714041707D4AD05F96027FA62FC916C81BA3C8601F7FF3115F17A117AD1B9A3D8438A731707A2D3B65BDA3846D293939CF94EBCC681E8115400454CF2CEA3769A614A9098CA62356B131EA22F4D634B56B365D7A430A3703967B50C6FCA93D11BD5ACC60048B5E00EAF353723D6DE878F8E5E4EA03BD43DF7229E6146DE307F9CC51B7F359F07042500AB5C24EE6F80EA8E1E50961BEC347949E5DD1918027A17196BABEE5790332B76D4AFFCD19143D7462177CDF72DE09BE64320C330090C1C6F1B059E81E02C312ABFC68F454D11EFCF1E0609584D06B09A08599D7A0BF5D63BB9F");
    /**
     * KEK RSA 私钥MAC
     */
    byte[] privateKeyRSAMAC = Forms.hexStringToByteArray("06E5A11D968C36DE");

    /**
     * KEK 加密的SM2私钥
     */
    byte[] privateKeySM2KEK = Forms.hexStringToByteArray("D3C5F579038C8BF3469879DD7F79C2E1B7FF47D7F2D5EFF5B01EFCE51C081D8067E06C0290F8EF6044210B43C894A77C");
    /**
     * KEK SM2 私钥MAC
     */
    byte[] privateKeySM2MAC = Forms.hexStringToByteArray("83E413861F0C0D15");


    /**
     * SM2 der编码的公钥
     */
    byte[] privateKeySM2DER = Forms.hexStringToByteArray("3059301306072A8648CE3D020106082A811CCF5501822D03420004B33D8A2F9E1E1FCA2E8CECCFFB166F52CC2ED0589C25464D0EF85DC87E0537DC16C0D542A53790967A1368B7084F6EFED51FC848D1E3B5370A99BDCB64D17C2F");
    /**
     * SM2 lmk加密的私钥
     */
    byte[] privateKeySM2 = Forms.hexStringToByteArray("66C9DDB0D6400EE059474F5C7339A296D5AA88F02AF031174F212EB6538C21908C4F5CA6457B435F");
    /**
     * SM2 保护密钥保护的私钥
     */
    byte[] privateKeyKEKSM2 = Forms.hexStringToByteArray("D3C5F579038C8BF3A1624E7DC142A863240A42642337355921C70A7547001B21A0C59D4E0800F99644210B43C894A77C");
    /**
     * SM2 MAC
     */
    byte[] privateKeyKEKSM2MAC = Forms.hexStringToByteArray("B9827812C2E18232");

    /**
     * 随机生成的sm2密钥 1002
     */
    byte[] publicSM2 = Forms.hexStringToByteArray("3059301306072A8648CE3D020106082A811CCF5501822D03420004D93204DF6335BEF43A90F8566CFB6FB5F7B10BE8082E9C0D9A5AA731F994AF07990FCB6913D902C4C9B8A84A3F96ADDD7BEF537D61404D56E58A68C756AEFD40");
    byte[] privateSM2 = Forms.hexStringToByteArray("6F26783DCE6D45B84D3FF39FFBDB365FE93B94EF15C39E00A09DE07212472FA68D1A3B721C09BB28");

    /**
     * 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("EE828FCCFAC494756468B1FECCE81192");
    byte[] sm4CV = Forms.hexStringToByte("BCC22E39C9B72764");

    byte[] sm4ProKeyCipher = Forms.hexStringToByte("7C78B0D533A10812FE9277504181C23F");
    byte[] sm4ProKeyCipherCV = Forms.hexStringToByte("8849C862448CFB73");

    byte[] newSM4 = Forms.hexStringToByte("AE62E4E90FA741090AECE0AC9923B885");
    byte[] newSM4KeyMAC = Forms.hexStringToByte("F7EBEA9FD38EBBD324E7EAAC9B7BE362");
    byte[] newSM4KeyTag = Forms.hexStringToByte("7C05A01A54B63CB90E0C8597DBED6D6D");

    byte[] sm4Key2 = Forms.hexStringToByte("40F7B1FA358855610EB13491B119A4AB");
    byte[] sm4Key2CV = Forms.hexStringToByte("955C2B5828299C51");

    /**
     * 产生对称密钥,保护密钥保护输出
     *
     * @throws TAException
     */
    @Test
    public void generateProtectionKey() throws TAException {
        /**
         * sm4
         * LMK加密的对称密钥:B36847D6E86EAB69E4EEB65558A2626C
         * 对称密钥的校验值:713CA557C1FE2AAB
         */
        ArrayList<byte[]> bytes = api.proGenSymmKey(Forms.hexStringToByteArray("B36847D6E86EAB69E4EEB65558A2626C"),
                TACryptConst.KEY_ALG_SM4, Forms.hexStringToByteArray("713CA557C1FE2AAB"), 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("30820122300D06092A864886F70D01010105000382010F003082010A0282010100A636C484374F9F039EB4318952B6BA5ABBE096F2B37B12DBC71A09F3B7BEEB83EB4A4BBBBDBBCC9332168E336981C919EF8BB734B3671DFEDCB79459401F95DDAA4EACECB36599451F9F77F5B01BF6B6AA1F94DE8BE5ED8B7BD52CA94929F7B0D3E8F5FDAFA322538AE32F89D7E3C1E4203120EDE6F213A3848F8ECF9E6836BE369A4658B6EB14D2FD3681488A3207CE0A5A9088011B2DA893C7F2C674843BB5254C30CB67D9C8182FEF284BB5CD8A239D6411EA199AD8B93EBE3442716FDAB44FB3932248C076C8794725CEEB5B76674B2B6DC605DC0F9835C6CCBBE4807A4F925065E02C65CAFE2D80A275BF5D096D2E07BA9ED5A75A10D425B03B84BB57990203010001"), 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("789F01F9CC1BE0FF7429D7EAB215ABA1"),TACryptConst.ENC_MODE_CBC, TACryptConst.KEY_TYPE_RULE, TACryptConst.KEY_ALG_AES128,
                Forms.hexStringToByte("AE6BA9133D0D4BB0090882E33F03D905D779785299F12C241936CB6AE45B9D2CB5C6B4E6C96D74BEB7D4A53684A18E0764DBE6A2383FB43C8CCCBDC1E84DF4D593141B302CB0F96074B32E06924F54AC342584EF47D41EF0022362A89F07B96071D3D0910C7A581FE0F7BC564F28107C9EBDD060AB11DC0700E3577606BCD666C93207E2AFDCF84E6FA7FE84A60BB39B0B0489EDDBEFB1C95768EA9010C993B2D51B8A752396FE585422F766CBAC3CCC7301C92483D726DEF325A685D861ABFFABF2C91022DB984D8E606CAA8AEE01DA969C72F81F0D13E96DCDE0DEAAF4309517618FB4C5BA6281F262C511E3A90F9ED952FD6D0ACEB6CCD4F5FA96DD6C15A2A2B848C1A224AAE1081102FC7313EB233112B1C0079352310E974EB1155A759374004095E2256B0ADC3BFFFF150AF071"), 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("C0C64CD82E3B2DC8C8F4D5A33F0EF6B4F5942AF6B880EE6A6AAB159C90C3F46175F2C068A54CF5BA4F0BCF7AC04E08E8"),
                b, Forms.hexStringToByte("75F2C068A54CF5BA4F0BCF7AC04E08E8"), 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("C0C64CD82E3B2DC8C8F4D5A33F0EF6B4F5942AF6B880EE6A6AAB159C90C3F46175F2C068A54CF5BA4F0BCF7AC04E08E8"), b, Forms.hexStringToByte("75F2C068A54CF5BA4F0BCF7AC04E08E8"), 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("83E265207D4566C7704DF9E6170181378CA028FB1EAA0BCB771DFD188CF5BEA899ECEF9213CA98D6D698CCE6072237768F514B04D68DA6B01400F69F93601976DCDFAE8F2EDDAA4F01BA8CE5E76A77AEB01BAB9D6E59A32B4E30B2B8D21D13B5C3510A1622190621BD3B0B5838A2CCBE423F4D3A7613CB69BBC9857E4BF5D08AAD77DDB96ECDD88989B885D44B909F502DC53A2FB4200FA714ECCFF100E7E986D76B68BD0BEFF5CA33CA698DA42F8B74FFBC09FB8F30483E416D0D2EAC6AF2B2A309F6762B5D292DA619C92428D1AB11A6931C81A859C79D8C01B441B1902ABE001BFF501DEE0E1E241E4567ECC74F9D4665AEA77C4F93AC312347A5087B686DC8361415A85197DB69CEEFD6D00CE94C34C290B8F79F10CC27A79D7C4D8F43736223576649E93457C75BA8C637927EC780A56B45163142DE1483777B4C8222C92B3C82AB372B3B0223D4EE246938EB85A7EC536DC77A291E152CF94E02465137DF2F25140669071913F868E58F379472235564F125B6C71C2705FE895ABEEFE33C656ACA7D489AD5C432B80AB9D8F732C03519F2E99F0DEAC4A7312FC351C059877BA09FB6455EFCB0D0DFE9F597416A5E1D88A7326C64D5539D91519935FADD5BE76EBB4D60FC57103CB8960890B4B1EC822C8D9781CF67B6DD1BE15E87406A0B0B5C06A69F6B07991C95B13CC0C4DBEA91589425E7C8D4E7CFE2CBBEC34D7705E8B52939D2E154B3435B7B4B8E41CD4DCEDF3892EF0F3352C8467CA46DB08A7DC93969E18B405F44508F919F4C0B3F2F7C0B79E661001B79FB0F0205A97CECFBE25DC4C711EA");

    byte[] srcRSACipherMAC = Forms.hexStringToByte("948D9944793CAFAB372E54468349B3E5");

    byte[] srcRSACipherTag = Forms.hexStringToByte("9C8A7CB4C6D1AE08775F0681ED497EDF");

    byte[] srcRSApublicKey = Forms.hexStringToByteArray("308186028180E14CAAFFCEC6D014457D7CA3E943DBABA1299BDBC17690C8E70F7BFA10EA02450805DA4C6CDC38BFBF1349C95B81A88177BA31C08E366EF965CA41EB36A2DACE611B80A752615A094B8291AAB6F8BB3A5894E72842371F34FA04C10DF42C2FEA95C51B9D49BE8B795E10474954FE01BAAC63532520069465FA62EDB266AADEBB020103");
    /**
     * RSA LMK加密的私钥
     */
    byte[] srcRSAprivateKey = Forms.hexStringToByteArray("000202703D0652C7027B7D94B45A896646A9DC7CA89825FB12121B3CC00E37BE933055D5C00E37BE933055D54718ADDAA677519BD9C054CA249B43888FE000B8AAC33BA87A2C326985704335EA54D7F171CABCAD5531B3ADF33255A24075EFFF62691D4375E6280A9442CA36AA46AC59FAB16D9A9A7A283440BB14BAB1E78DBE887AE93A2C94C547779190D3FA801379BA948537281EFEFE567FD963E5D6E5D442D908A68BB6E26F3776EA30B1136A3804844035E26308E9B44BE154E1D09382E5A72BD711A6936373A8C32B62AF88134690C30D8B5505004F3BA01D11D0D791C8FF53D0E0786ED192CF1105FCF82160921EEF23E7BD72F13587B316BD9A771CEABBD0186B45E09C86E718AD4E5444EFFE747FE0C39E85D6190F3347656E72F486C321D5EA0D42127149C99F4F799A31F91E5826B74FF720A6E3CC2BCBBF645DD3D4A6A7D0BC953B4CFEE4E0D2BABFD606292F9F2395464484C306FBD60E4DD293E5F56C60BF1482A05775F0EEBAFBF9B70841DDDCFC974DD4D87E54D6A6A7A1A585EF0F42B0763D5DD7B5ECA83AFE610C26C9EF559B7883AC4716240BDFDC91C6EA19A0C01BB9C053F2A9C7EBCAE7D0AA8FB0DB88EFCF9C50A134E04649DAFF21D724E5C3CC043DE950C2CF246392DC4CA592D28C5A959BEB80B304E3BD949AD33178C06209FE6EB7130A381DFFD80F916AE0E0DD8FFDD9C8C9895BC483993D6011754FAD3C9F83A59C31F47810F8B2B22E5F25EF13671DFF34ECB65DE71D5B13DC5880595BC60B18D4711AE4613C739E2A48B516F6233E9AA9834075CE58975907F06FBA3B85C97E2E90B60BFEF0F23527E770798B571BC7CE29B67920538D509C58B1D8F966AF7E5321CDB2386164844D2BCB");


    byte[] srcSM2Cipher = Forms.hexStringToByte("83E260209C09CEF21E1AD68B09EC5FA762164497DB6D7C6EEA5D58D14F7C0B8D670537112DFB030F");

    byte[] srcSM2CipherMAC = Forms.hexStringToByte("7DF725131F3E67547F029550F2F073E9");

    byte[] srcSM2CipherTag = Forms.hexStringToByte("A2181C58228D7A32AE37C072987D1B7E");

    byte[] srcSM2publicKey = Forms.hexStringToByteArray("3059301306072A8648CE3D020106082A811CCF5501822D03420004549EAF3A09B4F486171FF320B81C4037286FC68026AA6E0101D3108C0573CFB0FF431DF8D3F9E5A31C7DE80940637E036B2D6FD36A0F586D4CDC3A610A269E89");

    byte[] srcSM2privateKey = Forms.hexStringToByteArray("79E62264C314D1D3279D9B7752CD137AD4095864801607EB52B6AB9C6ADBF2BC777F8CBE7EC55699");


    /**
     * 大数据包加解密
     */
    @Test
    public void bigDataEnc() throws TAException {
        byte[] enc = api.bigDataEnc(Forms.hexStringToByteArray("6DF7292D86B674B6B81F7C94DDC967A0"), "AES/ECB/PKCS5Padding", "demaxiyazhili".getBytes(), new byte[0]);
        System.out.println(Forms.byteToHexString(enc));
        byte[] dec = api.bigDataDec(Forms.hexStringToByteArray("6DF7292D86B674B6B81F7C94DDC967A0"), "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("000204B07672172F114E8E847A5FB9EC3DD32CD1F063E78FE16508F3E13DDCEE227447EBE13DDCEE227447EB80D3FD7BAFF9D6FD4DE2225C31BAFF7C626E7DEFD52ED1EEF9195F538F89B902AF389CF4277EADC1FA18BED9044C4CBCDD6801DA9C8762A3E6715D93AF02D4665D1AE5669288EF9E429C46EDC366C4F60724DED14AE4A3870E6D75DA22CFC304C38B50394BC09F833D3A6A663F0E0863FB7DDBC0C83CD24690BF54B8A45053CAE10C22018D11C10F112B4EECA416D39FCEA9276C93DAE83D8B300E67545B897DCAAC0CF064C9A2F8EE61362AE90694EF300DC7B901F1F093BA167DA76CD5F1432024C8C8FC420BB182B3944F7E104DBAE51BD859F36E92AB32E21754B711288643FB3399B363F776CB614C5EC08569A0E457507D3CA53A56065ECEA0AC7A467E88C4A7D2B63BBF933FE69B64E8F43F766D3D5B219FF00882E85F4C8A9CAD86EE65ACE2129DB6B4EC760E6687DE96B9AFB6F2A98D3C4AFE0F05D4485ADC055580242DD1FAF07808FA75E85E102B879E680004F992979ACA6B6C54885B5A52FF1EA55B3EF9F787D395E2E500D1A8CDE83D7FC05DB124441F2234BC88B9286CA142B22601C5225F8E679CFD3F612E37CA39E67736175B4A298BD69625658664AF8A9B8045A4E3FE2CEF770BD6BF2CE7D6B7C0C72B55C23FA6D0437E2D4DEDE89BCFC77AC90EA1F5B72910A4449EED91BCB778CD86DA88DE8341940E7F4677EB7D322722876A893926326E19D32DF6653EB4068D3C05F24B854F4B77EB0059C7EECD4283CC65F31300FE0EEEA87E97CC39F74B2929847D1A7B5DC2C6281CB8FCB30AEB605155ACF0C3EBE0BFD5E652CCE11C7D59CF89929F2DAE619CB21C7F4E148436951E1EAC41508A51DE2835103892D0FEE9913E82C673470F764CED04F4A3F7512E7BCB38C11685ED5A03D9D3F82977F3D36D53E0E3116D424CFA246E8954136DA20B666C4CBE532CF177A48AD1F6BBA626240D032569FA4CC7158DDD94E800213FC2072A24389757CD97B3CF511D240DC8171593C8F1BCEE73D32A13C894BE1C3F03FC2A3098579D3E0F45F64C3E9E9846F11B3436664B5D591E9F4EF0F96A00AC6CA793215865404C9AB0424E3F5488B5A3AA87D57D90CC56ED5B9C647A38CBD41968AF759961F9B8D8048E1E93AD063199B8D75875578AA8E8409D7837B61C6D56B82A690E08BDF24FAE143BDC4FA8314881ACFCD6EE66F8158F3E446527CE883E1391901DD192B6859625FF2F77B2E22EE9CC3E97FBD4455DF2F4A772FB2962F9A3BCFF7ADA30D07BB53BB2B3C1F60AA4FBE541D2A02457342666FB560906BCD21C701488E6D4548505776190CB0CC79E1B9D1014D70ECE5A9E104608E7940C570960ACA0C6CAFBA80D0FB95E99B52D2E9FDAFE92A6786F14EF387AFF54F3607908408BFC1C31FDE0FFF8C75D1DF431F5275941F665005DD89F6E3F48CEFFD3746E33F63D0F616BA559A292095690B59B907907A41D69281CC90E3A2D68D66E74D44FF7A36AD370693883B9B6440A3674F94B42CC594CB9A56D37FA1C4D76F9A7DDA71D8CEA31D1397678B33A0ECCFE5095FCC98A8B6D30A3DE7EF1963D68A4B15EE45060FDA7EA3DBA42C936CBCDA2C99FBAD98F12DE1A4523A12F2F8D0C7818A1C5B6377A8499AE837EB0B233D98470234F3EAD29C2DAB368CF5463151BCB266DEF496D8E");
    byte[] publicRSA = Forms.hexStringToByte("3082010902820100EED2CF3C2E3624D65718E0F1CCE74F3D5CB93B4C1B3737161E7154AE0027FD911A901B040040FAE50F586AC6E3CC653ADA75F7CF7A36E18C3D662AA81AE25D05CBE5486ED432BCC3925324ADE4592E4577DC004503BC05F9D67AFCFAB58D14E294A8AC3979AE8DC0319F8E180BF948E9E3BE9527546999120EB88DEEF36EE5C589E00421B309145377730AD99337FDB8A1F01F191ED7F761854B86BAAA61253DF821B2C72FDD138134A848278FF94B660C47DEF24EB23163919F199D1637FC1B4E2AB0683CB17B07706D5D307F17D6A8916EAA92AB80B07E9F723C5A96AB382B90F4718E18A620556D927F5DA9529C22D5C701B8B1BB7836D351A815A69116110203010001");
    byte[] publicR77 = Forms.hexStringToByte("3082010A0282010100A636C484374F9F039EB4318952B6BA5ABBE096F2B37B12DBC71A09F3B7BEEB83EB4A4BBBBDBBCC9332168E336981C919EF8BB734B3671DFEDCB79459401F95DDAA4EACECB36599451F9F77F5B01BF6B6AA1F94DE8BE5ED8B7BD52CA94929F7B0D3E8F5FDAFA322538AE32F89D7E3C1E4203120EDE6F213A3848F8ECF9E6836BE369A4658B6EB14D2FD3681488A3207CE0A5A9088011B2DA893C7F2C674843BB5254C30CB67D9C8182FEF284BB5CD8A239D6411EA199AD8B93EBE3442716FDAB44FB3932248C076C8794725CEEB5B76674B2B6DC605DC0F9835C6CCBBE4807A4F925065E02C65CAFE2D80A275BF5D096D2E07BA9ED5A75A10D425B03B84BB57990203010001");
    @Test
    public void RSApriSign() throws TAException, IOException {
        byte[] bytes = api.RSAPriKeySign(privateRSA,TACryptConst.PADDING_MODE_NO, 4, 0,
                0, 0, Forms.hexStringToByte("9ECA5459BA0B5CA0CCBB2A01EA05DE319C9E97DF730F0E2A55E9DC2B6FFA85CE"));
        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("9ECA5459BA0B5CA0CCBB2A01EA05DE319C9E97DF730F0E2A55E9DC2B6FFA85CE"));
        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("BFA03DB9BD0A4DE4809B59B04BF663E8E541B0CF0017E0337342B8F7CDEB210C86429D87A51A7E2B4ED760C4BB49A1AD1DE0353B3204D39C8F6FF9DB789C8DEDCDD84012DDB532F3E4554F0C85DCEF1C7241C98888F9CC57D04E902ABD2F422884235FD9E0A80116771AC436ED1EDE46CF272FD1DD4D3A5174D2D178D9A21F3D"));
        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("5C59EBCD0A48E51038853E490C76AD83122964E3AA3EAB660966F67DE56722D02E3B477D257BDDB90CA2F901254544933BD0852BCF6E466CE91813AACF8A4AD2C65F2B78888AE249A948BCDCF3E2D0CDCC70DC3BA9445D3237B6D56A701D17E95576AD4FCF0A1D20DC5A0AAB878DADC04903CCE5B3D06219FDB4497905FBEA9E"), "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("20D90A83A4654FB89AD97E7FF9B178BAA58E12CE8E5C16DE0371B374F76DEFA5");

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

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

        boolean b = api.pubKeyVerify(0x0007, Forms.hexStringToByteArray("3059301306072A8648CE3D020106082A811CCF5501822D03420004E6BFD64E16F9FDE831FC2483A703F32D2925C126C435CF4FF0BC0187351E34F627E3421ACA51CB99CD452FA11B5B6BBB4AA31C2DBCC696FC57C8F9F8F01948FE"), 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("3059301306072A8648CE3D020106082A811CCF5501822D03420004A45246028D1FE13EAA9BAE7F47929AE6F9993CEEFEA16EB1358526C8D85277BD63F2EB9A1AD40BEEE37267F8F1F97E67BCE29A4E1CCAB0979A1E85F81010E042");
        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("3059301306072A8648CE3D020106082A811CCF5501822D03420004E70CB95894768A69B5A184C17B31251710B2B870BB99E0BE150EA2FAF1F4CEECF6B48055A4C790CDE94A1B179CC12A39A856755F6677E87905BD903987425AF3");

    byte[] sm2PrivateKey = Forms.hexStringToByte("4F23C664B68C8A38B31F52727C856211D8D21B1AC76F300D2CD027E5AFD566976CEA234A749F031D");

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

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



    byte[] sm2Key = Forms.hexStringToByte("3059301306072A8648CE3D020106082A811CCF5501822D03420004E70CB95894768A69B5A184C17B31251710B2B870BB99E0BE150EA2FAF1F4CEECF6B48055A4C790CDE94A1B179CC12A39A856755F6677E87905BD903987425AF3");
    byte[] sm2Cipher = Forms.hexStringToByte("83E260209C09CC3F010349772852D7CD2C3C77DAEBA956791067754DA7FCFD8880E68AC28BFFF0F3");
    byte[] sm2CipherMAC = Forms.hexStringToByte("8184BE3669B2D12AEB673814E59E7700");
    byte[] sm2CipherTag = Forms.hexStringToByte("8FD638CA4D7640BDE213F5777253D192");
    byte[] sm2PriKey = Forms.hexStringToByte("4F23C664B68C8A38B31F52727C856211D8D21B1AC76F300D2CD027E5AFD566976CEA234A749F031D");


    /**
     * 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("E9C17D82604F992BB3AB8FE0F766441DACC05EB779D1D1CC9C5FEFF671739A87274713242CBBA04161C3994EA264C30D82BB6DAF8E688D3BADC8768A18226D8EAEB984E5EA739C2E8792921F02AA612F5AB732FACEC8316B880499E6E70260333E9F29CEBCF3F8E10C151F79445276F6"));
        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("20D90A83A4654FB89AD97E7FF9B178BAA58E12CE8E5C16DE0371B374F76DEFA5"));
        System.out.println("ECC/SM2私钥签名结果(私钥受保护密钥保护):" + Forms.byteToHexString(bytes));

        boolean b = api.pubKeyVerify(7, sm2Key, Forms.hexStringToByteArray("20D90A83A4654FB89AD97E7FF9B178BAA58E12CE8E5C16DE0371B374F76DEFA5"), 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("9A9161F87BCBD3E9BC8866B8706E8F75B682DA2712E7E32A5D0E4867700D8233284BF4EA98E352BE74817D240D92347F969809BA54626192102086000756E2CFD98A3CC8923513B3BF72FA33B39CB999E15613440F2DAD9AE786E3D73349D78FA7915B3CB633EFD9A88E638D93297934"), "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("71802E75BD4D99E90996A9B9DA6616E9"),
                0,  Forms.hexStringToByteArray("B36847D6E86EAB69E4EEB65558A2626C"),
                new byte[0], new byte[0], 5, -1,-1, new byte[0], 0, 7,
                Forms.hexStringToByte("994056800038295C09C7F45977D291AA"));
        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("7C78EAFE26890D48096AB8141B1D5890BF1921DD899664A7E224C05DC30A7392CAA4BB0E518CBE5721DAC409F85B736A1DAEC40FAB410CA007C114574BAEAD1227560F1D2AE148884814872F0305F821F7245329ADED546F44C52C8F49EAC46647650D9B983224E9E005CFCAA88B019D"));

        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("6149EE02F14EE6420BC2B462003CCCE2413CE4911F5C36F720DD123DA9A432EEA17C534A8662F9B1E813C8A5FA929E9A06AC2CFDB2AAB68E66A58C9A4E0C76AF5126785160A665C23F22309ECBF48B8BAFA8BE9D41F334852649D5D204937A4EDA3B0A9B1A7B3054E1D9AE3BA2173028C3A0E2CE400522E06DCBAB44213A85B668764EC33EE71D372F5A904252A539AA"));

        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("5BD90CDDBC8645B41AB901DDD8EFE9956755D9560C9FAEB096B6E52CC003D04F"),
                Forms.hexStringToByteArray("F8B6B9D8BB7E4FD3"),
                TACryptConst.KEY_TYPE_SYMMETRY,
                TACryptConst.KEY_ALG_AES256,
                Forms.hexStringToByteArray("CFE8E3D44F753D3F065962462AA9C9E1FE295BC835E4A1FB88EF70B54E65E232"), b,
                Forms.hexStringToByteArray("8F2440B22092CA8757D8D807A832A19F"), TACryptConst.ENC_MODE_GCM, b, new byte[22],
                Forms.hexStringToByteArray("B5294D591009E19E780774B61BA48FA4"),
                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("CBDCCE33784FA93FBE0B3BAA46CF3557"),
                Forms.hexStringToByteArray("F6684895E1ABC2AD"),
                0,TACryptConst.KEY_ALG_SM4,
                Forms.hexStringToByteArray("6BFC84C39CB9277C06C7FA2A30C912A1"), b,
                Forms.hexStringToByteArray("AB75C62580061710B39327B45881F589"), TACryptConst.ENC_MODE_GCM,
                b, new byte[0], Forms.hexStringToByteArray("4A501743FA4B906244A0A8705192C1C8"),0,
                TACryptConst.KEY_ALG_SM4,
                Forms.hexStringToByteArray("CBDCCE33784FA93FBE0B3BAA46CF3557"),
                Forms.hexStringToByteArray("F6684895E1ABC2AD"), 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("83E260209C09CC3FEFDEFE7F4B620157A3F25E0B3098A4677DAF3A8E9DC327A17AEB2C8919E1E4CF"), b,
                Forms.hexStringToByteArray("E60EFC48823B17C51F68D0EB622298FB"),
                TACryptConst.ENC_MODE_GCM, b, new byte[16],
                Forms.hexStringToByteArray("B200ED220D49D855EC4438649057EB02"),
                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("566F7CE9E52CCA87FF02D7A7667E3F7C"), //GCM 模式解密时的 MAC 值
                Forms.hexStringToByteArray("DA23B170CEA626F4C772B3F2AE2CCA97"),//密钥密文
                Forms.hexStringToByteArray("7192C7C6F1EAAB72BFE8A51BA9256C87"),  //GCM tags
                6, //保护密钥加密模式
                new byte[16],//保护密钥IV
                new byte[16], //认证数据AAD
                Forms.hexStringToByteArray("8DE9DFEE4BE10827C1C08A38BDD8A92F"), //tags
                5,//保护密钥加密填充方式
                12, //会话密钥类型
                7,  //会话CMK 非对称密钥的算法标识
                Forms.hexStringToByteArray("420B9FE23A2B162F3C4574919E9EBD44040F7C5338CDE0C8311C88495D2F3604E9AFC80B18990EF5C6F3A93AB80B41458311EA9F9A1890752427E24F5062AD4A"),//会话私钥密文数据
                "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("0000000000000000000000000000000000000000000000000000000000000000E43101353F49C7164DAE6C691FC25CD494D9A28D0F6C4B51F3BB9DC85ADDBE09"), 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("3076301006072A8648CE3D020106052B8104002203620004491995797F5C99C17726E4841BE04D333C5BD3511819720388BD7264112905D3073FC25743EED2AE7D1448C2D2D9E014C640FC395CF19650A61D0ABC616D521050C45645477442F9BF8BE9BF81EAD69CDA6C63FCF5244A383C57DDB62465E63B"));
//        System.out.println("secp384r1协商结果:" + Forms.byteToHexString(bytes));
//        byte[] bytes1 = api.agreementKey(0x0007, 3, 6, Forms.hexStringToByte("3059301306072A8648CE3D020106082A811CCF5501822D03420004AC3DC24CE9883F26278E97A04D5409AA2A94D57FCE84E7630F4E46CFBED036A6B89791DF9A3DF50D67073CF246FC3406337B50E987F2AC3943D2FF5C7ECAD197"));
//        System.out.println("0x0007协商结果:" + Forms.byteToHexString(bytes1));
//        byte[] bytes2 = api.agreementKey(0x0007, 3, Forms.hexStringToByte("E59842CEEC68775E6AD78C7276AD2ADE0E27405E8B60FE02F7DF23E08F7F6B8D"), Forms.hexStringToByte("3059301306072A8648CE3D020106082A811CCF5501822D034200040EF69FB0C3739C3FDC16499AB96985EAD5CBEB4178A985A8FC10145979C315A5519C50B972EB19EA77A6AB74F345688B8458F1015885FCE435A4E3679DE0E34F"));
//        System.out.println("0x0007外部私钥明文协商结果:" + Forms.byteToHexString(bytes2));
//        byte[] bytes3 = api.agreementKey(0x039B, 0, 5, Forms.hexStringToByte("304A301406072A8648CE3D020106092B24030302080101030332000448D5FAD9CD434E60EF661B65289867B395461D868F7D34BABEEB5A20F7DF5543091DD740DD3780B5EBEF631615571ADC"));
//        System.out.println("0x039B协商结果:" + Forms.byteToHexString(bytes3));
        byte[] bytesA = api.agreementKey(0x019F, 3, 13, Forms.hexStringToByte("3059301306072A8648CE3D020106082A8648CE3D030107034200048D912010F06A7D4B5062F6DC192EEDC8C88FCB2D2830AB8573F0FB30532041D0788F227558F1DA9AC8CDF5E7FA72C9931FA90EE06B3CE07E13A7845A05BA7C73"));
        System.out.println(bytesA.length);
        System.out.println("0x0007协商结果:" + Forms.byteToHexString(bytesA));
        byte[] bytesB = api.agreementKey(0x019F, 3, 15, Forms.hexStringToByte("3059301306072A8648CE3D020106082A8648CE3D0301070342000481022BD6C8FFBBD2EC4B5A53F7000920D1581C0BC17B4C781627894B0979FFCA115C85C7AB0964E53872FBF0511FF6E7661CF94B7D82C8BF78D211B1FA73F271"));
        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 ? "成功":"失败"));

    }


}

相关文档