3. 加密SDK简介:常见SDK与加密模块
做对象存储加密,SDK 是我们的手和脚。你选哪个 SDK,决定了你能调用哪些加密能力、怎么写代码、踩哪些坑。今天我把三个最常用的 SDK——boto3、oss2、minio-py 拉出来过一遍,重点看它们的加密模块怎么用。
三巨头:boto3、oss2、minio-py
这三者分别对应 AWS S3、阿里云 OSS、MinIO(兼容 S3)。我用它们做过好几个生产项目,各有各的脾气。
| SDK 名称 | 目标平台 | 加密模块入口 | 我最常用的加密方式 |
|---|---|---|---|
| boto3 | AWS S3 / S3 兼容 | boto3.s3.transfer + Encryption 参数 |
SSE-S3 / SSE-KMS / SSE-C(客户端加密分离) |
| oss2 | 阿里云 OSS | oss2.crypto 子模块 |
OSS 服务端加密 + 客户端 RSA/AES |
| minio-py | MinIO / S3 兼容 | minio.commonconfig + 请求头注入 |
SSE-S3 / SSE-C(无原生 KMS 需自搭) |
我建议你这样记:boto3 功能最全但文档藏得深;oss2 国内生态友好但加密模块有版本断层;minio-py 轻量灵活但加密能力需自己拼。
boto3 的加密玩法
boto3 的加密大致分两条路:服务端加密 和 客户端加密。服务端最简单,传个参数就行。
import boto3
s3 = boto3.client('s3')
# SSE-S3(AWS 托管密钥)
s3.put_object(Bucket='my-bucket', Key='hello.txt', Body=b'data',
ServerSideEncryption='AES256')
# SSE-KMS(客户主密钥)
s3.put_object(Bucket='my-bucket', Key='hello.txt', Body=b'data',
ServerSideEncryption='aws:kms',
SSEKMSKeyId='alias/my-key')
客户端加密呢?boto3 自己没封装,你得用 cryptography 库手动加密再上传。我做过一个合规项目,客户要求密钥不出 VPC,只能用客户端加密——那次真是把 boto3 的传输管理器和加密流程拆了个遍。
下载时别忘了加 SSECustomerAlgorithm 和 SSECustomerKey 参数,否则会收到 403 AccessDenied。我第一次踩这个坑时排查了半小时……嗯,从那以后我写了个装饰器自动补请求头。
oss2:国内场景的主力
oss2 的加密模块在 oss2.crypto 下。它支持两种客户端加密:AES256 和 RSA。我上一家公司用阿里云 OSS 存用户证件,用的就是 RSA 信封加密。
import oss2
from oss2.crypto import RsaProvider
# 先生成 RSA 密钥对
private_key, public_key = RsaProvider.generate_key_pair(2048)
provider = RsaProvider(public_key, private_key)
bucket = oss2.CryptoBucket(
auth, 'https://oss-cn-hangzhou.aliyuncs.com', 'my-bucket', provider)
# 上传后自动加密,下载自动解密
bucket.put_object('secret.txt', b'sensitive data')
result = bucket.get_object('secret.txt')
print(result.read()) # 已解密
注意:CryptoBucket 内部把加密信息写进了对象的元数据。所以下载时必须用同一个 provider,否则解不出来。我记得有一次同事换了一台机器部署,忘了把 private_key 带过去,结果线上报错——对着日志看了半天才反应过来。
oss2 从 2.14.0 版本开始重构了加密模块。如果你发现 oss2.crypto 里没有 RsaProvider,先升级 SDK:pip install -U oss2。
minio-py:轻量但得自己动手
minio-py 本身没有独立的加密子模块。加密靠的是在请求时加 headers 参数。它支持 SSE-S3 和 SSE-C,但 SSE-KMS 需要你自己对接外部 KMS 服务。
from minio import Minio
client = Minio('play.min.io',
access_key='minioadmin',
secret_key='minioadmin',
secure=True)
# SSE-S3
client.put_object('my-bucket', 'hello.txt', data, length,
sse=SseS3())
# SSE-C(自定义密钥)
key = b'0123456789abcdef0123456789abcdef' # 32 字节
ssec = SseCustomerKey(key)
client.put_object('my-bucket', 'hello-c.txt', data, length, sse=ssec)
下载的时候呢?也得传同样的 sse 对象。否则 minio-py 会报 InvalidArgument。你想想看,这个设计其实逼着你把密钥管理做到调用层——稍微麻烦,但够安全。
我个人习惯在 minio-py 项目里封装一个加密助手类,统一管理 SSE-C 的密钥派生和请求头注入。这样业务代码不用操心加密细节。
核心加密模块对比
我把三个 SDK 的加密模块整理成一个速查表,方便你快速定位。
| 能力项 | boto3 | oss2 | minio-py |
|---|---|---|---|
| SSE-S3 原生 | ✅ ServerSideEncryption='AES256' |
✅ OSS 服务端默认加密 | ✅ SseS3() |
| SSE-KMS | ✅ 完整支持,可指定 Key ID | ✅ 通过 x-oss-server-side-encryption 头 |
⚠️ 需自己对接 KMS |
| SSE-C(自定义密钥) | ✅ 请求头参数 | ⚠️ 不推荐,用客户端加密代替 | ✅ SseCustomerKey() |
| 客户端加密(信封) | ⚠️ 无原生封装 | ✅ oss2.crypto 子模块 |
⚠️ 无原生封装 |
| 密钥管理集成 | ✅ AWS KMS、CloudHSM | ✅ 阿里云 KMS | ❌ 全靠自己 |
这几个 SDK 的加密模块实现差异不小。但核心逻辑一致:服务端加密靠参数/请求头,客户端加密靠 SDK 封装或手动加解密。
知识体系结构
下面这张图总结了三种 SDK 的加密模块、使用方式和适用场景。你可以把它当本章的知识地图。
如果你刚开始接触对象存储加密,我推荐先从 boto3 的 SSE-S3 入手。它最直观、调试工具最多。把这条路走通了,再去看 oss2 的信封加密和 minio-py 的 SSE-C,理解起来会快很多。