客户端加密是指将数据发送到OSS之前在用户本地进行加密。

完整的示例代码请参见GitHub

数据加密密钥的保存方式有如下两种:

  • 用户自主管理(RSA)
  • KMS托管

使用以上两种加密方式能够有效的避免密钥的泄漏,保护客户端数据安全,即使数据泄漏其他人也无法解密得到原始数据。

客户端加密详细信息请参见开发指南中的客户端加密SDK介绍

加密元信息

参数 描述 是否必需
x-oss-meta-oss-crypto-key 加密后的密钥。 经过RSA加密后再经过base64编码的字符串。
x-oss-meta-oss-crypto-start 随机产生的加密数据的初始值 。经过RSA加密后再经过base64编码的字符串。
x-oss-meta-oss-cek-alg 数据的加密算法,取值为AES/GCM/NoPadding。
x-oss-meta-oss-wrap-alg 数据密钥的加密算法。取值为rsa和kms。
x-oss-meta-oss-matdesc 内容加密密钥(CEK)描述,JSON格式。暂未生效。
x-oss-meta-unencrypted-content-length 加密前的数据长度。如未指定content-length则不生成该参数。
x-oss-meta-unencrypted-content-md5 加密前的数据的MD5。如未指定MD5则不生成该参数。

使用用户自主管理方式上传和下载文件

您可以使用用户自主管理方式上传和下载文件。代码如下:

# -*- coding: utf-8 -*-
import os
import oss2
from  oss2.crypto import LocalRsaProvider

# 阿里云主账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM账号进行API访问或日常运维,请登录 https://ram.console.aliyun.com 创建RAM账号。
auth = oss2.Auth('<yourAccessKeyId>', '<yourAccessKeySecret>')

# 创建存储空间,使用用户自主管理(RSA)方式加密,此方式只支持文件整体上传下载操作。
bucket = oss2.CryptoBucket(auth,'<yourEndpoint>', '<yourBucketName>', crypto_provider=LocalRsaProvider())

key = 'motto.txt'
content = b'a' * 1024 * 1024
filename = 'download.txt'


# 上传文件
bucket.put_object(key, content, headers={'content-length': str(1024 * 1024)})

# 下载文件
result = bucket.get_object(key)

# 验证
content_got = b''
for chunk in result:
    content_got += chunk
assert content_got == content

# 下载OSS文件到本地文件
result = bucket.get_object_to_file(key, filename)

# 验证
with open(filename, 'rb') as fileobj:
    assert fileobj.read() == content

os.remove(filename)

使用KMS托管方式上传和下载文件

  • 前提条件
    1. 已开通阿里云密钥管理服务。
    2. 已生成您所在地域的密钥ID。
    3. 已创建自定义授权策略(操作路径:控制台 > 访问控制 > 策略管理 > 自定义授权策略 > 新建授权策略),并为对应用户关联此策略。

    参考以下格式创建自定义策略:

    {
      "Version": "1",
      "Statement": [
        {
          "Effect": "Allow",
          "Action": [
            "kms:CreateKey",
            "kms:GenerateDataKey",
            "kms:ListKeys",
            "kms:Encrypt",
            "kms:Decrypt"
          ],
          "Resource": [
            "acs:kms:<yourRegion>:<yourloginUserId>:key/*"
          ]
        }
      ]
    }
    
  • 示例代码
    # -*- coding: utf-8 -*-
    import os
    import oss2
    from  oss2.crypto import AliKMSProvider
    
    # 阿里云主账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM账号进行API访问或日常运维,请登录 https://ram.console.aliyun.com 创建RAM账号。
    auth = oss2.Auth('<yourAccessKeyId>', '<yourAccessKeySecret>')
    
    # 创建存储空间,使用KMS托管方式加密,此方式只支持文件整体上传下载操作。
    bucket = oss2.CryptoBucket(auth,'<yourEndpoint>', 'liusiman123456',crypto_provider=AliKMSProvider('<yourAccessKeyId>', '<yourAccessKeySecret>', '<yourRegion>', '<yourCMK>', '1234'))
    
    key = 'motto.txt'
    content = b'a' * 1024 * 1024
    filename = 'download.txt'
    
    # 上传文件
    bucket.put_object(key, content, headers={'content-length': str(1024 * 1024)})
    
    # 下载文件
    result = bucket.get_object(key)
    
    # 验证
    content_got = b''
    for chunk in result:
        content_got += chunk
    assert content_got == content
    
    # 下载OSS文件到本地文件
    result = bucket.get_object_to_file(key, filename)
    
    # 验证
    with open(filename, 'rb') as fileobj:
        assert fileobj.read() == content
    
    os.remove(filename)