使用对称密钥
更新时间: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)来获取密钥材料(加密公钥和令牌)
- 加密自己的对称密钥
# 以aes256的导入为例
# 使用openssl生成一个256位的对称密钥
openssl rand -out KeyMaterial.bin 32
# 将加密公钥从16进制转成二进制文本
cat public_key_xxxxx.txt |xxd -ps -r > PublicKey.bin
# PKCS#1 v1.5 加密 待导入密钥二进制文本KeyMaterial.bin
openssl rsautl -encrypt -in KeyMaterial.bin -pkcs -inkey PublicKey.bin -keyform DER -pubin -out EncryptedKeyMaterial.bin
# 将加密后的结果进行base64加密
openssl enc -e -base64 -A -in EncryptedKeyMaterial.bin -out EncryptedKeyMaterial_base64.txt
# 最后将加密后的结果和令牌密钥填入。即可成功导入
通过java sdk导入
- 代码示例
import com.baidubce.BceClientException;
import com.baidubce.BceServiceException;
import com.baidubce.Protocol;
import com.baidubce.auth.DefaultBceCredentials;
import com.baidubce.services.kms.KmsClient;
import com.baidubce.services.kms.KmsClientConfiguration;
import com.baidubce.services.kms.model.*;
import javax.crypto.Cipher;
import javax.xml.bind.DatatypeConverter;
import java.security.KeyFactory;
import java.security.PublicKey;
import java.security.spec.X509EncodedKeySpec;
import java.util.Random;
public class testImportSymmetricKey {
public static void main(String[] args){
//String ACCESS_KEY_ID = "<AK>"; // 用户的Access Key ID
//String SECRET_ACCESS_KEY = "<SK>"; // 用户的Secret Access Key
String ENDPOINT = "https://bkm.bj.baidubce.com"; // kms域名
// 初始化一个KmsClient
KmsClientConfiguration config = new KmsClientConfiguration();
config.setCredentials(new DefaultBceCredentials(ACCESS_KEY_ID, SECRET_ACCESS_KEY));
config.setEndpoint(ENDPOINT);
config.setProtocol(Protocol.HTTPS); // 设置https协议
KmsClient client = new KmsClient(config);
try {
//产生一个32字节随机数
byte[] keyMaterial = new byte[32];
new Random().nextBytes(keyMaterial);
//创建一个AES_256待导入密钥
CreateKeyRequest createReq = new CreateKeyRequest();
createReq.setKeySpec("AES_256");
createReq.setKeyUsage("ENCRYPT_DECRYPT");
createReq.setOrigin("EXTERNAL");
createReq.setProtectedBy("HSM");
CreateKeyResponse createRes = client.createKey(createReq);
String keyId = createRes.getKeyMetadata().getKeyId();
//获取导入密钥参数
GetParametersForImportResponse getParametersRes = client
.getParametersForImport(new GetParametersForImportRequest(keyId,"BASE64"));
String pubKey = getParametersRes.getPublicKey();
String token = getParametersRes.getImportToken();
byte[] publicKeyDer = DatatypeConverter.parseBase64Binary(pubKey);
//解析成RSA的公钥
KeyFactory keyFact = KeyFactory.getInstance("RSA");
X509EncodedKeySpec spec = new X509EncodedKeySpec(publicKeyDer);
PublicKey publicKey = keyFact.generatePublic(spec);
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
byte[] cipherDer = cipher.doFinal(keyMaterial);
//加密后的密钥材料,需要进行base64编码
String encryptedKeyMaterial = DatatypeConverter.printBase64Binary(cipherDer);
ImportKeyRequest importReq = new ImportKeyRequest();
importReq.setEncryptedKey(encryptedKeyMaterial);
importReq.setImportToken(token);
importReq.setKeyId(keyId);
importReq.setKeySpec("AES_256");
importReq.setKeyUsage("ENCRYPT_DECRYPT");
KmsResponse importRes = client.importKey(importReq);
System.out.println(importRes.toString());
}catch (BceServiceException e) {
System.out.println(e.getMessage());
} catch (BceClientException e) {
System.out.println(e.getMessage());
} catch (Exception e) {
System.out.println(e.getMessage());
}
}
}