大数据加解密-使用数据密钥(DEK)进行文件加解密
引导式阅读
Python
大数据加解密-使用数据密钥(DEK)进行文件加解密
作者
c***r
上架时间
2024-01-11 11:32:36

1、介绍

什么是密钥管理服务?

密钥管理服务,密钥管理,即密钥管理服务(Key Management Service,KMS),是一种安全、可靠、简单易用的密钥托管服务,帮助您轻松创建和管理密钥,保护密钥的安全。KMS通过使用硬件安全模块(Hardware Security Module,HSM)保护密钥安全,帮助用户轻松创建和管理密钥,所有的用户密钥都由HSM中的根密钥保护,避免密钥泄露。 当有大量数据(例如:照片、视频或者数据库文件等)需要加解密时,用户可采用信封加密方式加解密数据,无需通过网络传输大量数据即可完成数据加解密。

您将学到什么?

如何通过Python版本的KMS SDK方式使用数据密钥(DEK)进行文件加解密

2、前置条件

  • 1、获取华为云开发工具包(SDK),您也可以查看安装Python SDK。
  • 2、您需要拥有华为云租户账号以及该账号对应的 Access Key(AK)和 Secret Access Key(SK)请在华为云控制台“我的凭证 > 访问密钥”页面上创建和查看您的AK/SK。具体请参见 访问密钥
  • 3、- 华为云 Python SDK 支持 python3.3以上 的版本。可执行 python --version 检查当前 python 的版本信息。
  • 4、用户需要在密钥管理控制台创建用户主密钥,算法为AES_256。
  • 5、用户需要准备一个名为FirstPlainFile.jpg的文件

3、SDK获取和安装

您可以通过pip安装SDK依赖包

pip install huaweicloudsdkcore pip install huaweicloudsdkkms

4、接口参数说明

关于接口参数的详细说明可参见:

a.创建数据密钥

b.解密数据密钥

5、代码示例

如何通过Python版本的KMS SDK方式使用用户主密钥(CMK)进行字符串加解密

import os import stat import secrets import hashlib from Crypto.Cipher import AES from huaweicloudsdkcore.auth.credentials import BasicCredentials from huaweicloudsdkcore.region.region import Region as coreRegion from huaweicloudsdkcore.http.http_config import HttpConfig from huaweicloudsdkkms.v2 import KmsClient from huaweicloudsdkkms.v2 import CreateDatakeyRequest from huaweicloudsdkkms.v2 import CreateDatakeyRequestBody from huaweicloudsdkkms.v2 import DecryptDatakeyRequest from huaweicloudsdkkms.v2 import DecryptDatakeyRequestBody __AES_KEY_BIT_LENGTH = "256" __AES_KEY_BYTE_LENGTH = "32" __AES_GCM_AAD_STR = b"Demo For AAD" __GCM_IV_LENGTH = 12 __FILE_FLAGS = os.O_WRONLY | os.O_CREAT | os.O_EXCL __FILE_MODE = stat.S_IRUSR | stat.S_IWUSR def file_encrypt(data, plain_key, nonce): """ 文件加密逻辑,其中__AES_GCM_AAD_STR,加密和解密需要保持一致 :param: data 待加密的字节数据 :param: plain_key 加密时使用的密钥 :param: nonce 也作初始向量 :return: a tuple with two items: - the cipher text, as ``bytes`` - the MAC tag, as ``bytes`` """ cipher = AES.new(bytes.fromhex(plain_key), AES.MODE_GCM, nonce=nonce) cipher.update(__AES_GCM_AAD_STR) return cipher.encrypt_and_digest(data) def file_decrypt(data, plain_key, nonce, cipher_tag): """ 文件解密逻辑,其中__AES_GCM_AAD_STR,加密和解密需要保持一致 :param: data 待解密的字节数据 :param: plain_key 解密时使用的密钥 :param: nonce 也作初始向量 :param: cipher_tag 作MAC值 :return: 密文对应的明文数据 """ cipher = AES.new(bytes.fromhex(plain_key), AES.MODE_GCM, nonce=nonce) cipher.update(__AES_GCM_AAD_STR) return cipher.decrypt_and_verify(data, cipher_tag) def file_sha256_sum(file_name): """ 计算文件摘要值 :param: file_name 待计算摘要的文件名 :return: 文件的在SHA256算法下的摘要值 """ with open(file_name, "rb") as f: sha256_sum = hashlib.sha256() sha256_sum.update(f.read()) return sha256_sum.hexdigest() if __name__ == "__main__": """ 基础认证信息: 认证用的ak和sk硬编码到代码中或者明文存储都有很大的安全风险,建议在配置文件或者环境变量中密文存放,使用时解密,确保安全; 本示例以ak和sk保存在环境变量中来实现身份验证为例,运行本示例前请先在本地环境中设置环境变量 - access_key: 华为云账号Access Key - secret_key: 华为云账号Secret Key, 敏感信息,建议密文存储 - iam_endpoint: 华为云IAM服务访问终端地址,详情见https://developer.huaweicloud.com/endpoint?IAM - kms_region_id: 华为云KMS支持的地域,详情见https://developer.huaweicloud.com/endpoint?DEW - kms_endpoint: 华为云KMS服务访问终端地址,详情见https://developer.huaweicloud.com/endpoint?DEW """ access_key = os.environ["HUAWEICLOUD_SDK_AK"] secret_key = os.environ["HUAWEICLOUD_SDK_SK"] iam_endpoint = "https://<IamEndpoint>" kms_region_id = "<RegionId>" kms_endpoint = "https://<KmsEndpoint>" # 用户主密钥ID KEY_ID = "xxxxxxxx-xxx-xxx-xxxx-xxxxxxxxxxxx" # 1.准备认证信息 credentials = BasicCredentials(access_key, secret_key).with_iam_endpoint(iam_endpoint) # 配置请求属性 http_config = HttpConfig.get_default_config() http_config.ignore_ssl_verification = True http_config.timeout = (60, 120) # 2.初始化SDK,传入认证信息与KMS的终端信息 client = KmsClient.new_builder().with_credentials(credentials) \ .with_region(coreRegion(id=kms_region_id, endpoint=kms_endpoint)) \ .with_http_config(http_config).build() # 3.创建数据密钥 create_data_key_request = CreateDatakeyRequest(body=CreateDatakeyRequestBody( key_id=KEY_ID, datakey_length=__AES_KEY_BIT_LENGTH )) create_data_key_response = client.create_datakey(request=create_data_key_request) # 生成Nonce random_iv = secrets.token_hex(__GCM_IV_LENGTH) # 4.加密文件,并存储 raw_file_path = "FirstPlainFile.jpg" encrypt_file_path = "SecondEncryptFile.jpg" with open(raw_file_path, "rb") as raw_file: raw_data = raw_file.read(os.path.getsize(raw_file_path)) cipher_text, tag_mac_value = file_encrypt(raw_data, create_data_key_response.plain_text, bytes.fromhex(random_iv)) with os.fdopen(os.open(encrypt_file_path, __FILE_FLAGS, __FILE_MODE), "wb") as encrypt_file: encrypt_file.write(cipher_text) # 5.解密文件,并存储 decrypt_data_key_request = DecryptDatakeyRequest( body=DecryptDatakeyRequestBody(key_id=KEY_ID, cipher_text=create_data_key_response.cipher_text, datakey_cipher_length=__AES_KEY_BYTE_LENGTH)) decrypt_data_key_response = client.decrypt_datakey(request=decrypt_data_key_request) decrypt_file_path = "ThirdDecryptFile.jpg" with open(encrypt_file_path, "rb") as encrypt_file: cipher_data = encrypt_file.read(os.path.getsize(encrypt_file_path)) plain_text = file_decrypt(cipher_data, decrypt_data_key_response.data_key, bytes.fromhex(random_iv), tag_mac_value) with os.fdopen(os.open(decrypt_file_path, __FILE_FLAGS, __FILE_MODE), "wb") as decrypt_file: decrypt_file.write(plain_text) # 6.比对文件是否一致 if file_sha256_sum(raw_file_path) != file_sha256_sum(decrypt_file_path): raise Exception("test case failed")

6、修订记录

发布日期 文档版本 修订说明
2023-09-11 1.0 文档首次发布