亚马逊AWS官方博客

云原生安全密钥管理服务为创新成长企业保驾护航

背景介绍

数据安全是每个企业都必须重视的问题。在处理客户敏感信息时,确保数据的安全和隐私对于赢得客户的信任至关重要。使用云安全服务可以有效保护您的数据安全,防止数据泄露和黑客攻击。在本文中,我们将讨论如何使用亚马逊云科技托管加解密相关安全服务来保障数据安全,从而帮助您赢得客户的信任。

本文目的

亚马逊云科技提供的服务可帮助您保护数据、免受未经授权的访问,提供加密、密钥管理服务。第一个场景,您的应用数据保存在 RDS 数据库,应用程序通过用户名密码访问数据库数据,用户名密码需要妥善保管,避免 Hard Code 在代码或配置文件中,一旦泄漏将造成数据损失。妥善保管的方式在亚马逊云科技有原生的服务,提供保管数据库密码的最佳实践。第二个场景,加密资产的公私钥对应着资金的地址和交易,对客户非常重要,一旦泄漏将造成资金损失,亚马逊云科技提供了原生的公私钥管理服务,并由您来控制谁可以访问私钥。

本文将介绍密钥生成和管理的具体场景和实现方案,场景包括 Amazon RDS 数据库密码管理,加密资产的私钥生成,加密资产的私钥使用,并提供演练步骤和参考以进行测试验证。

服务对比

密钥的生成和管理包括创建密钥,并授权服务或用户能安全的访问,使用密钥进行加密解密等操作,并能根据需要进行密钥的轮换、对密钥活动进行监控和审计、优化性能及降低成本等。亚马逊云科技为密钥生成和管理提供多种服务,Amazon KMS,CloudHSM 允许您安全地生成和管理加密密钥;Secrets Manager 使您安全的存储密钥,集中管理密钥的生命周期;Identity and Access Management (IAM) 使您能够安全地管理对亚马逊云科技服务和资源的访问,CloudTrail 提供日志记录功能以实现合规性和审计。

在安全合规性方面,Amazon Secrets Manager,KMS,CloudHSM 都是在经联邦信息处理标准(FIPS)140-2 验证的硬件基础之上构建而成,因此选择服务时,更多的是基于对 HSM 控制程度、适用灵活性和成本的需求寻找平衡。

为了对亚马逊云科技提供的三个密钥管理服务进行介绍,从多个维度进行比较,方便您更清晰的认识三个服务,并根据应用场景选择合适的服务:

Secrets Manager KMS CloudHSM
适用范围 安全的储存密钥 生成并使用密钥 生成并使用密钥
常见场景

1.储存 RDS 数据库密码

2.储存其他密钥

1.加密资产的私钥再加密

2.加密资产的公私钥生成

3.敏感数据加密和数字签名

FIPS 140-2 第 3 级合规性要求的应用程序和数据
密钥存储 底层由 KMS 提供密钥加密 多租户,FIPS 140-2 验证的 HSM(硬件安全模块) 单租户,FIPS 140-2 第 3 级 HSM(硬件安全模块)
密钥访问权限 基于身份和资源的 IAM 策略 基于身份和资源的 IAM 策略 客户自定义
密钥访问记录 CloudTrail CloudTrail CloudWatch

从上表所展示的各种服务的不同特征,我们总结了 Secrets Manager、KMS、CloudHSM 适用的一些常见场景:

  • Secrets Manager 适用于如数据库凭证管理包括存储和转动、私有 Token 存储的场景
  • KMS 适用于创建对称和非对称密钥以用来做基于 AES/RSA 算法的数据加密或是基于 ECC/RSA 的数字签名
  • CloudHSM 适合于对 HSM 有特殊访问管理要求、或者需要使用 FIPS 140-2 3 级验证的 HSM 来管理加密密钥的要求的场景

在应用场景中,有时单一服务即可满足要求如 Secrets Manager 储存 RDS 用户名密码,也可能会同时使用多种服务,比如加密资产的私钥通过 KMS 做一次加密,然后再将加密后的密文保存到 Secrets Manager 或者 RDS 中,需要使用私钥时从 Secrets Manager 或者 RDS 中获取到加密后的密文,再调用 KMS 进行解密后使用。

以下部分将对 RDS 数据库密码管理,加密资产的私钥生成,加密资产的私钥使用三种常见场景进行具体的方案描述。

场景和实现方案

Amazon RDS 数据库密码管理

场景描述:

客户端连接数据库,如何安全存储数据库凭证,使之不易被明文获取,并定期轮换数据库密码,而不需要修改应用代码。

实现方案:

使用 Secrets Manager 直接保存凭证。此时连接数据库需拥有 Secrets Manager 密钥权限和 Secrets Manager 中加密使用的 KMS 密钥相关权限,客户端调用 Secrets Manager API 获得数据库凭证用户和密码。

如上图所示,可将数据库凭证填入并选择相应的数据库实例在 Secrets Manager 实现保存,加密密钥可选择 KMS 默认密钥或者客户托管密钥。Secrets Manager 支持自动轮换 RDS 密码,启用密钥轮换时可配置轮换计划和轮换函数,轮换函数可设为默认的 Lambda 函数或者配置为自定义的 Lambda 函数。详情可参考文档

密钥保存在 Secrets Manager 后,可在 Lambda 中使用 AWS Parameters and Secrets Lambda Extension 并调用相应 API ,便捷地从 AWS Secrets Manager 中检索密钥,从而使用获得的密钥连接相应的数据库,代码示例如下:

secrets_url = ('http://localhost:' + port +'/secretsmanager/get?secretId=' + creds_path)
headers = { "X-Aws-Parameters-Secrets-Token": os.environ.get('AWS_SESSION_TOKEN') }
secret_string = http.request("GET", secrets_url, headers=headers)

rds_host =  secret_string['host']
rds_db_name = secret_string['dbname']
rds_username = secret_string['username']
rds_password = secret_string['password']

conn = pymysql.connect(host=rds_host, user=rds_username, passwd=rds_password, db=rds_db_name, connect_timeout=5)

Web3/PKI 的私钥托管

场景描述:

以太坊是流行的 Web3 核心基础设施,以太坊账户包括一个公私钥对,从公钥可以派生出以太坊地址,随意分发,而私钥则需要安全的存储和管理起来,主要挑战是如何安全地管理私钥。客户可以选择自己生成公私钥,或选择托管服务,Amazon KMS 托管服务可以用于托管以太坊私钥。

实现方案:

基于 Amazon KMS 的以太坊账号示例,参考 Github-AWS-Samples-kms-ethereum-accounts 。该示例代码说明了如何在 KMS 上托管以太坊账户(私钥/公钥)以及如何使用 KMS 在以太坊交易上创建有效的签名。架构图如下所示:

以太坊使用 ECDSA(椭圆曲线数字签名算法)标准 secp256k1 算法,由 Amazon KMS 密钥规格 ECC_SECG_P256K1 提供支持。使用 Amazon KMS 创建非对称密钥,选择 “登录并验证”,密钥规格选择 “ECC_SECG_P256K1”。

创建完成后,通过 Public key 可以转换得出以太坊地址,通过 KMS 可以进行以太坊交易签名,包括 EIP-1559 ,具体细节和代码实现可参考系列博客 Use Key Management Service (AWS KMS) to securely manage Ethereum accounts

Public key 转换以太坊地址代码示例:

pub_key = get_kms_public_key(params.get_kms_key_id())
_logger.info('pub_key encoded: {}'.format(pub_key))

eth_addr = calc_eth_address(pub_key)
eth_checksum_addr = w3.toChecksumAddress(eth_addr)

加密资产的私钥签名交易时通过调用 KMS 的 sign 接口来实现,代码示例:

client = boto3.client('kms')
response = client.sign(
    KeyId=aws_key_arn,
    Message=message.encode(),
    MessageType="RAW",
    SigningAlgorithm="ECDSA_SHA_256"
)

Web3/PKI 的私钥使用

场景 1 描述:

用户可以在亚马逊云上安全的使用私钥,例如进行交易签名,同时避免在代码或者配置文件中暴露私钥,私钥通过亚马逊云加密服务进行加密,密文可以安全的保存在 Amazon RDS 或 Secrets Manager 等存储中,使用时通过 IAM 权限控制谁可以解密密文。

实现方案:

使用 Amazon KMS 创建一个对称加密算法的 KEY,使用这个 KEY 对私钥进行加密,得到密文,可以选择将密文保存在 Amazon RDS 或 Secrets Manager ,应用希望使用私钥进行交易时,从存储中查到密文,调用 KMS 对密文解密得到私钥明文,进行交易签名。其中 KMS 的加密和解密需要设置密钥策略,允许哪些 IAM User 或 IAM Role 使用这个 KEY。

场景 2 描述:

用户可以在隔离的 CPU 和内存安全环境中使用和处理私钥,例如进行交易签名,同时阻止父 EC2 实例上的用户和应用程序获取私钥,免受来自本地操作系统潜在漏洞的攻击,比如黑客通过代码漏洞攻击内存,拿到私钥滥用发起交易。

实现方案:

基于 EC2 Enclave 构建一个隔离的零信任私钥使用环境,参考博客 ,使用流程如下所示:

另外如果希望在容器应用中使用 Enclave,目前支持在 Amazon EKS 中使用,参考 文档

密钥访问授权

在上述场景中,可见无论是对数据进行加解密或是进行数字签名,Secrets Manager 和 KMS 密钥的访问权限都很重要。Secret Manager 和 KMS 两种服务都支持基于身份和基于资源的权限策略,在策略评估逻辑中基于资源的策略先于基于身份的策略,同时在跨账号场景下,使用基于资源的权限策略可避免使用 AssumeRole 增加复杂度,因此基于资源的策略在实际使用中往往更受青睐。

下图为 KMS 的密钥策略视图。

以场景 RDS 数据库密码为例,假定 Account1 中使用 Secrets Manager 对 RDS 进行数据库密钥进行管理, Account2 中的身份希望获得密钥访问权限进而连接数据库,可结合基于资源的权限策略和基于身份的策略完成如下跨账号密钥访问和密钥解密授权:

步骤 1:创建资源策略允许 Account2 中的 ApplicationRole 访问 Account1 中的密钥,将其附加到 Account1 中 Secrets Manager 的密钥策略中。

步骤 2:创建资源策略允许 Account2 中的 ApplicationRole 使用 Account1 中的 KMS 密钥来解密,将其添加到 Account1 中 KMS 密钥的密钥策略中。

步骤 3:创建身份策略允许 Account2 中的 ApplicationRole 访问 Account1 中密钥,并通过使用 Account1 中的加密密钥来解密密钥,将其附加到 Account2 中的身份。

完成以上步骤 Account2 中 ApplicationRole 即可访问并解密保管在 Account1 Secrets Manager 中的由 KMS 加密后的 RDS 密钥,最终实现 RDS 连接 。

除此之外,Secrets Manager 和 KMS 服务也支持跨区域使用,可采用多区域复制以适应多区域使用密钥的场景以及作为灾备方案。具体可参考 AWS KMS 中的多区域密钥将 Amazon Secrets Manager 密钥复制到其他 AWS 区域 。

总结

企业在上云过程中,云计算的数据安全往往备受企业关注,无论是业务驱动或是合规驱动,数据存储加密都是业界公认的数据安全控制。加密离不开算法和密钥,在算法公开的场景中,密钥就成为关键安全变数,因此密钥管理成为云上数据安全的重点。

本文对亚马逊云科技上的多种密钥管理服务进行了介绍对比,并提供了对几种常见密钥管理场景的方案介绍和动手步骤,帮助读者结合自身实际场景更好的选择合适的密钥管理方案。

本篇作者

王寒冰

亚马逊云科技解决方案架构师,负责基于 AWS 云计算方案的架构咨询和设计实现,具有丰富的解决客户实际问题的经验,专注于容器化,无服务器化的应用。

杜晨曦

AWS 解决方案架构师,负责基于 AWS 云计算方案架构的咨询和设计,在国内推广 AWS 云平台技术和各种解决方案。