如何在AWS存储SSL/TLS证书及私钥,供非AWS应用调用API
解决方案:将SSL/TLS证书与私钥存储在AWS并供外部应用调用
核心思路
使用AWS的Secrets Manager(推荐,专为敏感凭证设计)或Systems Manager Parameter Store存储证书与私钥,通过IAM权限控制访问,应用启动时通过AWS SDK拉取并加载到HTTP客户端。
步骤1:选择存储服务并上传凭证
选项A:AWS Secrets Manager(推荐)
适合存储敏感凭证,自带加密、自动轮换审计日志功能:
- 将PEM格式的证书和私钥打包成JSON结构(示例):
{ "client_cert": "-----BEGIN CERTIFICATE-----\n...证书内容...\n-----END CERTIFICATE-----", "client_key": "-----BEGIN PRIVATE KEY-----\n...私钥内容...\n-----END PRIVATE KEY-----" } - 控制台上传:
- 进入AWS Secrets Manager控制台,点击「创建密钥」
- 选择「其他类型的密钥」,粘贴上述JSON内容,设置密钥名称(如
external-api-client-credentials)
- CLI上传(替代方式):
aws secretsmanager create-secret \ --name external-api-client-credentials \ --secret-string '{"client_cert":"PEM证书内容","client_key":"PEM私钥内容"}' \ --region 你的AWS区域
选项B:Systems Manager Parameter Store(低成本替代)
适合对成本敏感的场景,使用SecureString类型加密存储:
- 分别上传证书和私钥为两个独立参数:
# 上传证书 aws ssm put-parameter \ --name "/external-api/client-cert" \ --type "SecureString" \ --value "PEM证书内容" \ --region 你的AWS区域 # 上传私钥 aws ssm put-parameter \ --name "/external-api/client-key" \ --type "SecureString" \ --value "PEM私钥内容" \ --region 你的AWS区域
步骤2:配置IAM权限
为应用使用的IAM用户(或角色)添加最小权限策略,确保仅能访问目标凭证:
针对Secrets Manager的策略示例
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": "secretsmanager:GetSecretValue", "Resource": "arn:aws:secretsmanager:你的区域:你的账号ID:secret:external-api-client-credentials-XXXXXX" } ] }
针对Parameter Store的策略示例
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": "ssm:GetParameter", "Resource": [ "arn:aws:ssm:你的区域:你的账号ID:parameter/external-api/client-cert", "arn:aws:ssm:你的区域:你的账号ID:parameter/external-api/client-key" ], "Condition": {"BoolEquals": {"ssm:WithDecryption": true}} } ] }
步骤3:应用中拉取并加载凭证
以Python为例,使用AWS SDK获取凭证并配置HTTP客户端:
基于Secrets Manager的实现
import boto3 import json import requests from requests.adapters import HTTPAdapter from urllib3.poolmanager import PoolManager import ssl # 初始化Secrets Manager客户端 secrets_client = boto3.client( 'secretsmanager', region_name='你的AWS区域', aws_access_key_id='你的IAM用户AccessKey', aws_secret_access_key='你的IAM用户SecretKey' ) # 拉取凭证 secret_response = secrets_client.get_secret_value(SecretId='external-api-client-credentials') credentials = json.loads(secret_response['SecretString']) cert_data = credentials['client_cert'] key_data = credentials['client_key'] # 自定义SSL适配器,加载证书和私钥 class CertAdapter(HTTPAdapter): def init_poolmanager(self, connections, maxsize, block=False): ssl_ctx = ssl.create_default_context(ssl.Purpose.SERVER_AUTH) ssl_ctx.load_cert_chain(certfile=None, cert_data=cert_data, keyfile=None, key_data=key_data) self.poolmanager = PoolManager(num_pools=connections, maxsize=maxsize, block=block, ssl_context=ssl_ctx) # 配置请求会话并发起请求 session = requests.Session() session.mount('https://', CertAdapter()) response = session.get('https://目标API地址/接口路径') print(response.status_code)
关键注意事项
- 应用的AWS凭证(AccessKey/SecretKey)需通过环境变量或本地配置文件加载,绝对不能硬编码到代码库
- 可在应用中添加缓存逻辑,避免每次请求都拉取凭证,减少延迟和AWS API调用次数
- 确保证书和私钥为标准PEM格式,无多余换行或格式错误
内容的提问来源于stack exchange,提问作者CN1002
相关产品推荐
相关产品推荐

