使用对称密钥
更新时间:2023-03-07
对称加密是最常用的数据加密保护方式,百度智能云密钥管理服务(Key Management Service,KMS,以下简称 KMS )提供了简单易用的接口,方便客户在云上轻松的实现数据加解密功能。
创建对称密钥
- 点击 创建密钥 按钮,选择 密钥类型,选择 密钥材质,填写 密钥描述,即可完成对称用户主密钥( Customer Master Key,以下简称 CMK )的创建。
算法类型
目前 KMS 支持的对称加密算法类型如下:
算法 长度 规格 保护级别 AES 128 AES_128 HSM AES 256 AES_256 HSM AES 256 BAIDU_AES_256 HSM SM1 128 SM1_128 HSM SM4 128 SM4_128 HSM
密钥材质
创建 CMK 所必须的内容,支持 KMS生成 以及 外部导入 两种方式。
- KMS生成 :自动为用户创建密钥材料,并使用密钥材质生成 CMK。
- 外部导入 :创建一个待导入的 CMK,需要用户将自己的密钥材质导入到 CMK 后方可正常使用。只有 AES_128 / AES_256 / SM1_128 / SM4_128 这四种规格支持自主密钥材质的导入。
导入对称密钥材质
- 先创建一个密钥材质类型为外部导入的对称密钥,点击 获取密钥参数 。
- 点击 确认,生成 加密公钥 和 令牌 。令牌有效期为24小时。
- 获取 加密公钥 和 令牌 后,使用加密公钥对需要导入的对称密钥进行加密。将加密后的密钥材质和令牌一同上传,即可完成自主密钥材质的导入。
- 导入成功后,CMK 的状态会从 待导入 变更为 已启用 。
导入对称密钥(AES_256)过程示例
通过控制台导入
1.在控制台或者通过接口创建一个 AES_256 的待导入对称密钥:
- 创建完毕后点击获取密钥材料或者利用接口(/?action=GetParametersForImport)来获取密钥材料(加密公钥和令牌)
- 加密自己的对称密钥
Plain Text
1# 以aes256的导入为例
2# 使用openssl生成一个256位的对称密钥
3openssl rand -out KeyMaterial.bin 32
4# 将加密公钥从16进制转成二进制文本
5cat public_key_xxxxx.txt |xxd -ps -r > PublicKey.bin
6# PKCS#1 v1.5 加密 待导入密钥二进制文本KeyMaterial.bin
7openssl rsautl -encrypt -in KeyMaterial.bin -pkcs -inkey PublicKey.bin -keyform DER -pubin -out EncryptedKeyMaterial.bin
8# 将加密后的结果进行base64加密
9openssl enc -e -base64 -A -in EncryptedKeyMaterial.bin -out EncryptedKeyMaterial_base64.txt
10# 最后将加密后的结果和令牌密钥填入。即可成功导入
通过java sdk导入
- 代码示例
Plain Text
1import com.baidubce.BceClientException;
2import com.baidubce.BceServiceException;
3import com.baidubce.Protocol;
4import com.baidubce.auth.DefaultBceCredentials;
5import com.baidubce.services.kms.KmsClient;
6import com.baidubce.services.kms.KmsClientConfiguration;
7import com.baidubce.services.kms.model.*;
8
9
10import javax.crypto.Cipher;
11import javax.xml.bind.DatatypeConverter;
12import java.security.KeyFactory;
13import java.security.PublicKey;
14import java.security.spec.X509EncodedKeySpec;
15import java.util.Random;
16
17public class testImportSymmetricKey {
18 public static void main(String[] args){
19 //String ACCESS_KEY_ID = "<AK>"; // 用户的Access Key ID
20 //String SECRET_ACCESS_KEY = "<SK>"; // 用户的Secret Access Key
21 String ENDPOINT = "https://bkm.bj.baidubce.com"; // kms域名
22 // 初始化一个KmsClient
23 KmsClientConfiguration config = new KmsClientConfiguration();
24 config.setCredentials(new DefaultBceCredentials(ACCESS_KEY_ID, SECRET_ACCESS_KEY));
25 config.setEndpoint(ENDPOINT);
26 config.setProtocol(Protocol.HTTPS); // 设置https协议
27 KmsClient client = new KmsClient(config);
28 try {
29 //产生一个32字节随机数
30 byte[] keyMaterial = new byte[32];
31 new Random().nextBytes(keyMaterial);
32 //创建一个AES_256待导入密钥
33 CreateKeyRequest createReq = new CreateKeyRequest();
34 createReq.setKeySpec("AES_256");
35 createReq.setKeyUsage("ENCRYPT_DECRYPT");
36 createReq.setOrigin("EXTERNAL");
37 createReq.setProtectedBy("HSM");
38 CreateKeyResponse createRes = client.createKey(createReq);
39 String keyId = createRes.getKeyMetadata().getKeyId();
40 //获取导入密钥参数
41 GetParametersForImportResponse getParametersRes = client
42 .getParametersForImport(new GetParametersForImportRequest(keyId,"BASE64"));
43 String pubKey = getParametersRes.getPublicKey();
44 String token = getParametersRes.getImportToken();
45 byte[] publicKeyDer = DatatypeConverter.parseBase64Binary(pubKey);
46 //解析成RSA的公钥
47 KeyFactory keyFact = KeyFactory.getInstance("RSA");
48 X509EncodedKeySpec spec = new X509EncodedKeySpec(publicKeyDer);
49 PublicKey publicKey = keyFact.generatePublic(spec);
50 Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
51 cipher.init(Cipher.ENCRYPT_MODE, publicKey);
52 byte[] cipherDer = cipher.doFinal(keyMaterial);
53 //加密后的密钥材料,需要进行base64编码
54 String encryptedKeyMaterial = DatatypeConverter.printBase64Binary(cipherDer);
55
56 ImportKeyRequest importReq = new ImportKeyRequest();
57 importReq.setEncryptedKey(encryptedKeyMaterial);
58 importReq.setImportToken(token);
59 importReq.setKeyId(keyId);
60 importReq.setKeySpec("AES_256");
61 importReq.setKeyUsage("ENCRYPT_DECRYPT");
62 KmsResponse importRes = client.importKey(importReq);
63 System.out.println(importRes.toString());
64 }catch (BceServiceException e) {
65 System.out.println(e.getMessage());
66 } catch (BceClientException e) {
67 System.out.println(e.getMessage());
68 } catch (Exception e) {
69 System.out.println(e.getMessage());
70 }
71 }
72}