对称密钥导入密钥材料步骤

用户主密钥(CMK)是KMS的基本资源,由密钥ID、基本元数据(如密钥状态等)以及用于加密、解密数据的密钥材料组成。默认情况下,当您创建主密钥时,会由KMS生成密钥材料。您也可以选择创建密钥材料来源为外部的密钥,此时,KMS将不会为您创建的CMK生成密钥材料,您可以将自己的密钥材料导入到CMK中。
 
创建外部密钥
前置步骤
 
在创建密钥页面,密钥类型选择“对称”,轮转周期为“关闭”,密钥来源选择“外部”。
 
勾选我了解使用外部密钥材料的方法和意义,单击确认。
 
密钥参数下载
进入该外部密钥详情页,单击“获取导入密钥材料参数”,在弹窗中:
 
选择下载算法类型和加密算法。
 
算法类型主要有RSA_2048和EC_SM2。
 
单击下载按钮,文件以压缩包的形式下载,里边包含两个文件:“导入令牌”和“加密公钥”。导入令牌与加密密钥材料的公钥具有绑定关系,一个令牌只能为其生成时指定的主密钥导入密钥材料。导入令牌的有效期为24小时,在有效期内可以重复使用,失效以后需要获取新的导入令牌和加密公钥。
 
加密密钥材料
根据选择的加密算法来加密用户自己的密钥。
 
RSA_2048例子:
 
Security.addProvider(new BouncyCastleProvider());
 
KeyFactory keyFact = KeyFactory.getInstance("RSA");
 
//RSA公钥
 
String encryptPublicKey = "xxxxxx”
 
byte[] publicKeyDer = DatatypeConverter.parseBase64Binary(encryptPublicKey);
 
ASN1Sequence as = DERSequence.getInstance(publicKeyDer);
 
byte[] m =((ASN1Integer)as.getObjectAt(0)).getValue().toByteArray();
 
byte[] e = ((ASN1Integer)as.getObjectAt(1)).getValue().toByteArray();
 
RSAPublicKeySpec pubKey = new RSAPublicKeySpec(new BigInteger(1, m), new BigInteger(
 
PublicKey pk =keyFact.generatePublic(pubKey);
 
//用户密钥的产生:AES_256时为32,SM4时为16
 
byte[] keyMaterial = new byte[32];
 
new Random().nextBytes(keyMaterial);
 
System.out.println("密钥明文base64结果:" + Base64.getEncoder().encodeToString(keyMaterial)
 
//RSA加密方法为RSAES_OAEP_SHA_256为SHA-256,RSAES_OAEP_SHA_1为SHA-1
 
String hashFunc = "SHA-256";
 
Cipher oaepFromAlgo = Cipher.getInstance("RSA/ECB/OAEPWith" + hashFunc + "AndMGF1Pad
 
OAEPParameterSpec oaepParams = new OAEPParameterSpec(hashFunc, "MGF1", new MGF1Param
 
oaepFromAlgo.init(Cipher.ENCRYPT_MODE, pk, oaepParams);
 
byte[] cipherDer = oaepFromAlgo.doFinal(keyMaterial);
 
System.out.println("密钥明文加密结果:" + Base64.getEncoder().encodeToString(cipherDer));
 
 
 
EC_SM2例子:
 
Security.addProvider(new BouncyCastleProvider());
 
//公钥
 
String srcKey = "xxxxxxxxxxx”
 
X509EncodedKeySpec eks = new X509EncodedKeySpec(Base64.getDecoder().decode(srcKey));
 
KeyFactory kf = KeyFactory.getInstance("EC", BouncyCastleProvider.PROVIDER_NAME);
 
BCECPublicKey bcecPublicKey =  (BCECPublicKey) kf.generatePublic(eks);
 
ECParameterSpec parameterSpec = bcecPublicKey.getParameters();
 
ECDomainParameters domainParameters = new ECDomainParameters(parameterSpec.getCurve(), parameterSpec.getG(),
 
        parameterSpec.getN(), parameterSpec.getH());
 
ECPublicKeyParameters ecPublicKeyParameters = new ECPublicKeyParameters(bcecPublicKey.getQ(), domainParameters);
 
SM2Engine engine = new SM2Engine(SM2Engine.Mode.C1C3C2);
 
ParametersWithRandom pwr = new ParametersWithRandom(ecPublicKeyParameters, new SecureRandom());
 
engine.init(true, pwr);
 
//用户密钥的产生:AES_256时为32,SM4时为16
 
byte[] keyMaterial = new byte[32];
 
new Random().nextBytes(keyMaterial);
 
System.out.println("mingwen(OAEP):" + Base64.getEncoder().encodeToString(keyMaterial));
 
byte[] p = engine.processBlock(keyMaterial, 0, keyMaterial.length);
 
byte[] cipher = new byte[p.length - 1];
 
System.arraycopy(p,1,cipher,0,cipher.length);
 
System.out.println("加密结果:" + Base64.getEncoder().encodeToString(cipher));
 
导入密钥材料
单击“导入密钥材料”弹出导入密钥材料框,如下图所示:
 
加密密钥材料:需上传字符格式文件。
 
导入令牌:需上传字符格式文件。
 
密钥材料过期时间:默认选择永不过期,如不勾选,需手动选择过期时间。
 
单击“确定”校验密钥材料,校验成功后,密钥材料导入成功。导入密钥材料时,可以将从未导入过密钥材料的外部密钥进行导入,也可以重新导入已经过期和已被删除的密钥材料,或者重置密钥材料的过期时间。密钥材料首次被导入后,后续导入的密钥材料需与首次上传的密钥材料为同一个。
 
注意:
 
请确保您使用了符合要求的随机源生成密钥材料。
 
密钥材料可被删除
 
1. 您导入的密钥材料可以直接调用接口进行删除,也可以设置过期时间,在密钥材料过期后进行删除(CMK不会被删除)。
 
每个CMK只能拥有一个密钥材料
 
1. 当导入的密钥材料被删除后,可以再次导入相同的密钥材料使得CMK再次可用,因此您需要自行保存密钥材料的副本。
 
2. 每个CMK只能拥有一个导入密钥材料。当您将一个密钥材料导入CMK时,该CMK将与该密钥材料绑定,即便密钥材料已经过期或者被删除,也不能导入其他密钥材料。如果您需要轮换使用外部密钥材料的CMK,只能创建一个新的CMK然后导入新的密钥材料。
 
3. CMK具有独立性。例如:您使用CMK加密的数据,无法使用其他CMK进行解密,即便这些CMK都使用相同的密钥材料。
 
只能导入128位或256位对称密钥作为密钥材料。