本文档主要介绍了通过调用Java接口生成工作密钥和进行通用数据加解密的操作方法。

整体流程

  1. 初始化SDK。具体内容请参见初始化SDK
  2. 调用Java接口生成工作密钥、进行数据加密和解密。具体内容请参见调用Java接口生成工作密钥调用Java接口进行数据加密调用Java接口进行数据解密
  3. 配置Java接口。具体内容请参见配置Java接口

初始化SDK

使用以下方法初始化SDK。
hsmGeneralFinancehsm=hsmGeneralFinance.getInstance("./cacipher.ini");

调用Java接口生成工作密钥

调用以下Java接口生成工作密钥。
hsm.genWorkKey(keyType,algFlag,keyIndex,keyLable);

返回值

返回两个值:
  • 0号索引下:密钥在LMK下加密的密文。
  • 1号索引下:密钥校验值。

抛出异常

cn.tass.exceptions.TAException //接口自定义异常。

接口定义

public String[] genWorkKey(String keyType,
                                    char keyFlag,
                                    int storeKeyIndex,
                                    String storeKeyLabel)
                              throws cn.tass.exceptions.TAException

请求参数

参数名称 参数类型 参数描述
keyType String 密钥类型。支持密钥类型编码和密钥类型名称两种格式。例如:ZEK/DEK可以传"00A"和"ZEK/DEK"两种格式。取值:
  • 000:ZMK/KEK
  • 001:ZPK
  • 002:PVK/TPK/TMK
  • 003:TAK
  • 008:ZAK
  • 009:BDK
  • 00A:ZEK/DEK
  • 00B:TEK
  • 011:KMC
  • 109:MK-AC/MDK
  • 10C:HMAC
  • 209:MK-SMI
  • 309:MK-SMC
  • 402:CVK
  • 409:MK-DAK
  • 509:MK-DN
algFlag char 在LMK下加密的密钥密文标识。取值:
  • Z:单倍长DES密钥
  • X:双倍长3DES密钥
  • Y:三倍长3DES密钥
  • U:双倍长的3DES算法密钥
  • T:三倍长的3DES算法密钥
  • R:16字节SM4密钥
  • P:16字节SM1密钥
  • L:16字节AES密钥
  • M:AES-192算法密钥
  • N:AES-256算法密钥
KeyIndex int 密钥存储索引。取值范围:1~2048。
KeyLabel String 密钥存储标签。包含0~16个ASII字符。
说明 在云密码机内部存储密钥时标记密钥的标签说明。

请求示例

keyType:00A
algFlag:R
keyIndex:1
KeyLabel:test

调用Java接口进行数据加密

调用以下Java接口进行数据加密。

hsm.generalDataEnc(algType,keyType,sm4SymmKey,disperFactor,sessionType,sessionFactor,padFlag,inData,IV);

返回值

加密之后的密文数据。

抛出异常

cn.tass.exceptions.TAException //接口自定义异常。 

接口定义

public byte[] generalDataEnc(int algType,
                             String keyType,
                             Object key,
                             String disperFactor,
                             Int sessionType,
                             String sessionFactor,
                             Int padFlag,
                             byte[] inData,
                             String IV)
                      throws cn.tass.exceptions.TAException

请求参数

参数名称 参数类型 参数描述
algType int 加密算法模式。取值:
  • 0:ECB模式加密
  • 1:CBC模式加密
  • 2:CFB模式加密
  • 3:OFB模式加密
  • 4:CTR模式加密(16字节分组长度)
keyType String 加密数据的源密钥类型,支持密钥类型名称和密钥类型编码两种格式。例如:ZEK/DEK可以传"00A"和"ZEK/DEK"两种格式。取值:
  • 000:KEK
  • 109:MDK
  • 309:MK-SMC
  • 00A:ZEK/DEK
  • 00B:TEK
  • 011:KMC
key Object 加密数据密钥的索引或密文。
  • 当随机对称密钥的入参数据类型为int时,通过密钥索引调用密钥。
  • 当随机对称密钥的入参数类型为String时,按LMK加密的密钥密文调用密钥。
disperFactor String 密钥分散因子的n级分散因子进行串联,且每级分散因子必须为16个字节。
说明 针对敏感数据加密场景该参数取值为空字符串或NULL。
sessionType int 密钥分散因子的n级分散因子进行串联,且每级分散因子必须为16个字节。
说明 针对敏感数据加密场景该参数取值为空字符串或NULL。
sessionFactor String 会话密钥因子。
  • sessionType为1时,该参数为8字节(16H)。
  • sessionType为2时,该参数为16字节(32H)。
  • sessionType为5时,该参数为16字节(32H)。
说明 针对敏感数据加密场景该参数取值为空字符串或NULL。
padFlag int PAD填充标识。取值:
  • 0:PBOC 2 .0填充模式
  • 1:ISO/IEC 9797-1的PADDING模式2
  • 2:ISO/IEC 9797-1的PADDING模式1
  • 3:ANSI X9.23
  • 4:PKCS#5
  • 5:NoPadding模式
  • 10:PBOC 3.0填充模式
  • 11:左填充+ISO/IEC 9797-1
说明 针对敏感数据加密场景该参数取值为1。
inData byte[] 输入的明文数据。
说明 您可以根据应用业务自行输入数据内容。
IV String 初始向量。仅当algType取值为1234时支持该参数。
  • 密钥算法为64分组,该参数为8字节(16H)。
  • 密钥算法为128分组,该参数为16字节(32H)。
说明 ECB加密算法模式不需要IV,该参数取值为空字符串或NULL。

请求示例

algType:1
keyType:"00A"
key:symmKey[0] //加密的对称密钥密文,使用EVSM内部的索引密钥,使用内部密钥时为int类型。
disperFactor:null
sessionType:0
sessionFactor:null
padFlag:1
inData:根据用户业务自行输入数据内容。
IV:"00000000000000000000000000000000"

调用Java接口进行数据解密

调用以下Java接口进行数据解密。

hsm.generalDataDec(algType,keyType,sm4SymmKey,disperFactor,sessionType,sessionFactor,padFlag,symmEnc,IV);

返回值

解密后的数据。

抛出异常

cn.tass.exceptions.TAException //程序运行异常。   

接口定义

public byte[] generalDataDec(int algType,
                            String keyType,
                             Object key,
                            String disperFactor,
                            int sessionType,
                            String sessionFactor,
                             int padFlag,
                            byte[] inData,
                             String IV)
                      throws cn.tass.exceptions.TAException

请求参数

参数名称 参数类型 参数描述
algType int 加密算法模式。取值:
  • 0:ECB模式加密
  • 1:CBC模式加密
  • 2:CFB模式加密
  • 3:OFB模式加密
  • 4:CTR模式加密(16字节分组长度)
keyType String 密钥类型。取值:
  • MK-SMC
  • ZEK
  • DEK
  • TEK
key Object 加密数据的密钥索引或密文。
disperFactor String 密钥分散因子的n级分散因子进行串联,且每级分散因子必须为16个字节。
说明 针对敏感数据加密场景该参数取值为空字符串或NULL。
sessionType int 会话密钥的产生模式。取值:
  • 0:不产生会话密钥。
  • 1:ECB模式加密8字节会话密钥因子,得到8字节会话密钥。
  • 2:ECB模式加密16字节会话密钥因子,得到16字节会话密钥。
  • 3:密钥的左右8字节异或,得到8字节会话密钥。
  • 4:取密钥的左8字节作为会话密钥。
  • 5:CBC模式加密16字节会话密钥因子,得到16字节会话密钥。
说明 针对敏感数据加密场景该参数取值为空字符串或NULL。
sessionFactor String 会话密钥因子。
  • sessionType为1时,该参数为8字节(16H)。
  • sessionType为2时,该参数为16字节(32H)。
  • sessionType为5时,该参数为16字节(32H)。
说明 针对敏感数据加密场景该参数取值为空字符串或NULL。
padFlag int PAD填充标识。取值:
  • 0:PBOC 2 .0填充模式
  • 1:ISO/IEC 9797-1的PADDING模式2
  • 2:ISO/IEC 9797-1的PADDING模式1
  • 3:ANSI X9.23
  • 4:PKCS#5
  • 5:NoPadding模式
  • 10:PBOC 3.0填充模式
  • 11:左填充+ISO/IEC 9797-1
说明 针对敏感数据加密场景该参数取值为1。
inData byte[] 待解密的数据。
IV String 初始向量。仅当algType取值为123时支持该参数。
  • 密钥算法为64分组,该参数为8字节(16H)。
  • 密钥算法为128分组,该参数为16字节(32H)。

请求示例

algType:1
keyType:"00A"
key:symmKey[0] //加密的对称密钥密文,使用EVSM内部的索引密钥,使用内部密钥时为int类型。
disperFactor:null
sessionType:0
sessionFactor:null
padFlag:1
inData:自行输入加密后的数据。
IV:"00000000000000000000000000000000"

配置Java接口

您可以通过文件形式或者内容形式配置Java接口。
  • 文件形式:支持直接将配置文件绝对路径传入初始化接口内。示例:
    [LOGGER]
    logsw=error
    logPath=./
    
    [HOST1]
    hsmModel=SJJ1310
    linkNum=-5
    host=192.168.19.19
    port=8018
    timeout=5
    ifHeart=yes
    文件格式要求:
    分类 要求 示例
    注释 注释行以符号“#”起始,不支持行内注释。 #内容形式中的属性字段与文件形式中的属性字段保持一致。
    配置域 配置域以方括号“[”和“]”标识。
    说明 配置域键名不区分大小写,为了便于区分建议配置域使用大写。
    [LOGGER]
    配置项 配置项格式:“键名(Key)=键值(Value)”。 linkNum=-5
    配置内容 支持使用空白字符(空格或制表符)等对内容进行对齐操作。
    说明
    • 您可以在接口内拼装字符串传递配置。
    • 使用“{”和“}”,表示包括所有内容;使用“;”,表示换行。
    Java接口中配置文件的基本属性配置域包括日志属性EVSM属性应用属性等,日志属性EVSM属性的属性字段说明请参见下表。
    属性分类 配置域 属性字段 属性字段说明
    日志属性 [LOGGER] logsw 设置日志类别的开关,每种日志通过独立的关键字开启。取值:
    • error:错误日志
    • debug:调试日志
    logPath 设置日志文件的保存目录。
    说明 您需确保配置文件的目录已经存在,且应用系统具有写入权限。
    EVSM属性 [HOSTn]
    说明 n为该EVSM在当前配置文件中从1开始的序号,Java接口会按顺序读取多个EVSM的属性,直到最后1个序号。
    hsmModel VSM类型标识,用于指定EVSM驱动。默认值SJJ1310
    linkNum 与云密码机建立长连接的数量。默认值-10
    说明 数字前的负号(-)表示仅使用连接池,如果数字前没有负号表示优先使用连接池。优先使用连接池时,业务并发过高则Java接口中可能会创建短连接处理业务,对系统资源造成较大的影响。
    host EVSM主机服务IP地址,支持设置成域名形式。
    port EVSM主机服务端口。
    timeout 超时时间。单位为秒,默认值6秒。
    connTimeout 指定Java接口与逃生服务器建立网络连接的超时时间。该属性字段不存在时,使用timeout的取值。
    readTimeout 指定Java接口从逃生服务器读取信息的超时时间。该属性字段不存在时,使用timeout的取值。
    socketProtocol 通讯协议,支持TLSv1.2等版本协议。默认值TCP
  • 内容形式:支持直接将配置信息以字符串的形式传入初始化接口内。示例:
    # 内容形式中的属性字段与文件形式中的属性字段保持一致。
    Stringconfig=
    "{"
    +"[LOGGER];"
    +"logsw=error;logPath=./;"
    +"[HOST1];"
    +"hsmModel=SJJ1310;"
    +"host=192.168.19.19;"
    +"port=8018;"
    +"connTimeout=5;"
    +"}";

示例

public class SensitiveDataEnc {

    public static void main(String[] args) throws TAException {
        // 接口初始化,采用配置文件的方式。
        hsmGeneralFinance hsm = hsmGeneralFinance.getInstance("./cacipher.ini");
        // 接口初始化2,采用配置内容的方式。
//        String config =
//                "{"
//                        + "[LOGGER];"
//                        + "logsw=error;logPath=./;"
//                        + "[HOST 1];"
//                        + "hsmModel=SJJ1310;"
//                        + "host=192.168.19.19;"
//                        + "port=8018;"
//                        + "connTimeout=5;"
//                        + "}";
//
//        hsmGeneralFinance hsm = hsmGeneralFinance.getInstance(config);

        // 测试1产生随机密钥keyIndex为可变参数。
        // 当该密钥索引值取值为0时,表示不需要加密机保存生成的该条随机对称密钥。
        // 当keyIndex取值为1~2048时,表示将对称密钥储存在加密机中,且执行覆盖操作(相同索引执行覆盖操作)。
        int keyIndex = 0;

        switch (keyIndex) {
            case 0:
                // 产生随机SM4算法对称密钥。
                String keyType = "00A";
                char algFlag = 'R';
                String keyLable = "sm4Key";
                // 调用产生随机密钥接口。
                String[] symmKey = hsm.genWorkKey(keyType, algFlag, keyIndex, keyLable);
                System.out.println("对称密钥lmk下的密文值:" + symmKey[0]);
                System.out.println("对称密钥校验值:" + symmKey[1]);

                // 测试2。
                String str = "要加密的数据";
                // CBC模式。
                int algType = 1;
                // 密钥类型固定。
                keyType = "00A";
                // 执行加密的对称密钥密文。
                String sm4SymmKey = symmKey[0];
                // 也可以使用加密机内部的索引密钥,使用内部密钥时为int类型。
                String disperFactor = null;
                int sessionType = 0;
                String sessionFactor = null;
                // 遵循强制80填充。
                int padFlag = 1;
                byte[] inData = str.getBytes();
                String IV = "00000000000000000000000000000000";
                // 调用数据加密接口。
                byte[] symmEnc = hsm.generalDataEnc(algType, keyType, sm4SymmKey, disperFactor, sessionType, sessionFactor,
                        padFlag, inData, IV);
                System.out.println("16进制字符串输出对称加密结果:" + Forms.byteToHexString(symmEnc)
                        + ",如果进行解密,可使用接口功能函数'Forms.hexStringToByte()'将16进制字符串转换为byte[]参与解密。");
                // 调用数据解密接口。
                byte[] symmDec = hsm.generalDataDec(algType, keyType, sm4SymmKey, disperFactor, sessionType, sessionFactor,
                        padFlag, symmEnc, IV);
                System.out.println("解密结果与加密数据比较结果:" + Arrays.equals(symmDec, inData));
                System.out.println("还原解密结果,通过字符集还原原文:" + new String(symmDec));
                break;
            // 此时生成对称密钥到1号索引位置,若已经存在,会执行覆盖操作。
            case 1:
                str = "要加密的数据";
                // CBC模式。
                algType = 1;
                // 密钥类型固定。
                keyType = "00A";
                // 执行加密的对称密钥密文。
                int sm4SymmKeyIndex = 1;
                // 也可以使用加密机内部的索引密钥,使用内部密钥时为int类型。
                disperFactor = null;
                sessionType = 0;
                sessionFactor = null;
                // 遵循强制80填充。
                padFlag = 1;
                inData = str.getBytes();
                IV = "00000000000000000000000000000000";
                // 调用数据加密接口。
                symmEnc = hsm.generalDataEnc(algType, keyType, sm4SymmKeyIndex, disperFactor, sessionType, sessionFactor,
                        padFlag, inData, IV);
                System.out.println("16进制字符串输出对称加密结果:" + Forms.byteToHexString(symmEnc)
                        + ",如果进行解密,可使用接口功能函数'Forms.hexStringToByte()'将16进制字符串转换为byte[]参与解密。");
                // 调用数据解密接口。
                symmDec = hsm.generalDataDec(algType, keyType, sm4SymmKeyIndex, disperFactor, sessionType, sessionFactor,
                        padFlag, symmEnc, IV);
                System.out.println("解密结果与加密数据比较结果:" + Arrays.equals(symmDec, inData));
                System.out.println("还原解密结果,通过字符集还原原文:" + new String(symmDec));
                break;
            default:
                break;
        }

    }

}