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 的加密模块、使用方式和适用场景。你可以把它当本章的知识地图。

加密 SDK 知识结构图 加密 SDK 知识结构 加密 SDK 总览 boto3 AWS S3 + 兼容存储 oss2 阿里云 OSS minio-py MinIO / S3 兼容 服务端 / 客户端加密 SSE / 信封加密 SSE-S3 / SSE-C ServerSideEncryption CryptoBucket / provider sse=SseS3() / SseCustomerKey() 使用场景速览 • boto3:AWS 生态、需要 KMS 集成、企业级合规 • oss2:阿里云用户、国内部署、信封加密需求 • minio-py:自建存储、轻量项目、数据主权敏感

如果你刚开始接触对象存储加密,我推荐先从 boto3 的 SSE-S3 入手。它最直观、调试工具最多。把这条路走通了,再去看 oss2 的信封加密和 minio-py 的 SSE-C,理解起来会快很多。