密码机实例是密码机的硬件加密模块虚拟化形成的资源,具备对数据的加解密运算能力,可以实现加密服务的所有功能。本文介绍如何使用密码机实例。
前提条件
步骤一:创建密码机实例
步骤二:启用并配置密码机实例
步骤三:配置密码机实例管理工具
您可以使用密码机实例管理工具来管理和配置密码机,包括密钥管理、配置服务器端口等。
注意 密码机实例管理工具仅支持安装在Windows操作系统。
步骤四:使用密码机实例
您可以从步骤三:配置密码机实例管理工具获取到的密码机软件包中找到密码机的开发手册、SDK测试程序等。在完成密码机实例配置后,您可以参考开发手册,调用API接口使用密码机实例。
以GVSM为例,您可以使用其中的测试用例《JceTestMain.java》来测试密码机实例。代码示例如下:
注意 您需要将用例中的IP地址(121.41.XX.XX)修改为密码机实例分配的私网IP地址。
import cn.com.tass.jce.castle.hsm.connector.pool.PooledConfigReader;
import cn.com.tass.jce.castle.tc.encodings.Hex;
import javax.crypto.*;
import java.security.*;
import java.util.*;
public class APITest {
public static void main(String[] args) throws Exception {
//加载配置
String config = "{"
+ "[LOGGER];"
+ "logsw=debug,error;"
+ "logPath=./;"
+ "[HOST 1];"
+ "hsmModel=GHSM;"
+ "host=121.41.XX.XX;"
+ "linkNum=-3;"
+ "port=9021;"
+ "timeout=5;"
+ "}";
PooledConfigReader.setConfig(config);
//产生随机数
testGenRandom();
//SM2签名 验签
testOutKeySM2SignAndVeirfy();
//对称密钥加解密数据
testOutKeyAES128EncAndDec();
}
/**
* 外部密钥AES128加解密
*/
public static void testOutKeyAES128EncAndDec() {
try {
byte[] myAAD = Hex.decode("31313131313131313131313131313131");
//产生密钥
KeyGenerator keyGenerator = KeyGenerator.getInstance("AES", "TASS");
keyGenerator.init(128);
SecretKey key = keyGenerator.generateKey();
byte[] iv = Hex.decode("31313131313131313131313131313131");
byte[] plain = Hex.decode("31313131313131313131313131313131");
//调用接口进行内部密钥加解密
symEncAndDec("AES128 out key", key, "AES", plain, iv, myAAD);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* ECB、CBC 对称加密
*
* @param flag 标识
* @param key 密钥
* @param alg 算法名称
* @param plain 待加密的数据
* @param iv IV值
* @param add GCM模式下的add值
*/
private static void symEncAndDec(String flag, Key key, String alg, byte[] plain, byte[] iv, byte[] add) {
try {
//ECB/NoPadding
Cipher encipher = Cipher.getInstance(alg + "/ECB/NoPadding", "TASS");
Cipher decipher = Cipher.getInstance(alg + "/ECB/NoPadding", "TASS");
encipher.init(Cipher.ENCRYPT_MODE, key);
decipher.init(Cipher.DECRYPT_MODE, key);
//加密
byte[] resultEnc = encipher.doFinal(plain);
//System.out.println("("+flag+")"+alg + "/ECB/NoPadding" + " enc result = " + new String(Hex.encode(resultEnc)));
//解密
byte[] resultDec = decipher.doFinal(resultEnc);
//System.out.println("("+flag+")"+alg + "/ECB/NoPadding" + " dec result = " + new String(Hex.encode(resultDec)));
if (!verifyResult(plain, resultDec)) {
System.err.println("(" + flag + ")" + alg + "/ECB/NoPadding" + "解密失败");
System.out.print("\n");
} else {
System.out.println("(" + flag + ")" + alg + "/ECB/NoPadding" + "解密成功");
System.out.print("\n");
}
byte[] newPlain = Hex.decode("313131313131313131313131313131313233");
} catch (Exception e) {
e.printStackTrace();
}
}
public static boolean verifyResult(byte[] enc, byte[] dec) {
return Arrays.equals(enc, dec);
}
/**
* SM2外部密钥签名验签
*/
public static void testOutKeySM2SignAndVeirfy() {
try {
//待签名的原文数据
byte[] src = Hex.decode("313233");
//使用KeyPairGenerator产生密钥对充当外部密钥
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("SM2", "TASS");
keyPairGenerator.initialize(256);
KeyPair keyPair = keyPairGenerator.generateKeyPair();
//开始签名
Signature sign = Signature.getInstance("SM3withSM2", "TASS");
sign.initSign(keyPair.getPrivate());
sign.update(src);
byte[] signResult = sign.sign();
System.out.println("SM3withSM2 out key sign result = " + new String(Hex.encode(signResult)));
//开始验签
Signature verify = Signature.getInstance("SM3withSM2", "TASS");
verify.initVerify(keyPair.getPublic());
verify.update(src);
boolean verifyResult = verify.verify(signResult);
System.out.println("SM3withSM2 out key verify result = " + verifyResult);
//计算摘要值
MessageDigest digest = MessageDigest.getInstance("SM3", "TASS");
byte[] digestData = digest.digest(src);
//SM3withSM2ForHash开始签名
sign = Signature.getInstance("SM3withSM2ForHash", "TASS");
sign.initSign(keyPair.getPrivate());
sign.update(digestData);
signResult = sign.sign();
System.out.println("SM3withSM2ForHash int key sign result = " + new String(Hex.encode(signResult)));
//SM3withSM2ForHash开始验签
verify = Signature.getInstance("SM3withSM2ForHash", "TASS");
verify.initVerify(keyPair.getPublic());
verify.update(digestData);
verifyResult = verify.verify(signResult);
System.out.println("SM3withSM2ForHash int key verify result = " + verifyResult);
System.out.print("\n");
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 产生随机数
*/
public static void testGenRandom() {
try {
SecureRandom instance = SecureRandom.getInstance("HSM", "TASS");
instance.nextInt();
byte[] bytes = new byte[1024];
instance.nextBytes(bytes);
//输出随机数
System.out.println("1024 random : " + new String(Hex.encode(bytes)));
System.out.print("\n");
} catch (Exception e) {
e.printStackTrace();
}
}
}
更多操作
为密码机实例创建集群
您可以将处于不同的密码机实例加入到同一集群进行统一管理,为业务应用提供密码计算的高可用性、负载均衡以及横向扩展的能力。创建集群的具体操作,请参见使用密码机实例集群。
修改密码机实例配置
密码机实例未加入集群时,您可以修改密码机实例所属的VPC、VPC子网、私网IP地址和密码机实例白名单;密码机实例加入集群后,您只能修改密码机实例的私网IP地址。
- 在实例列表页面,找到目标密码机实例,在操作列选择 。
- 在密码机实例配置对话框,修改密码机实例的配置,然后单击确定。
停用密码机实例
重置密码机实例或者从集群中删除密码机实例前,您需要先停用密码机实例的业务功能。
注意
- 停用会断开密码机实例的网络连接,请谨慎操作。
- 不允许停用集群中的主密码机实例。
重置密码机实例
停用密码机实例后,您可以通过重置密码机实例,恢复密码机实例为出厂状态,即未初始化状态。
注意 重置将清空密码机实例中的数据,并恢复到出厂状态,请谨慎操作。
- 在实例列表页面,找到目标密码机实例,在操作列单击重置。
- 在弹出的对话框,再次单击重置。
恢复密码机实例
通过恢复密码机实例,重新启用已被停用的密码机实例业务。