服务器端加密

当您在设置了服务器端加密的存储空间(Bucket)中上传文件(Object)时,OSS对收到的文件进行加密,再将得到的加密文件持久化保存。当您通过GetObject请求下载文件时,OSS自动将加密文件解密后返回给用户,并在响应头中返回x-oss-server-side-encryption,用于声明该文件进行了服务器端加密。

说明

关于响应头中x-oss-server-side-encryption的更多信息,请参见响应头

使用场景

OSS通过服务器端加密机制,提供静态数据保护。适合于对文件存储有高安全性或者合规性要求的应用场景。例如,深度学习样本文件的存储、在线协作类文档数据的存储。

加密方式

OSS针对不同使用场景提供了两种服务器端加密方式,您可以根据实际使用场景选用。

加密方式

功能描述

使用场景

注意事项

费用说明

使用KMS托管密钥进行加解密(SSE-KMS)

使用KMS托管的默认CMK(Customer Master Key)或指定CMK进行加解密操作。数据无需通过网络发送到KMS服务端进行加解密。

因安全合规的要求,需要使用自管理、可指定的密钥。

  • 用于加密Object的密钥也会被加密,并写入Object的元数据中。

  • KMS托管密钥的服务器端加密方式仅加密Object数据,不加密Object的元数据。

KMS服务侧产生少量的KMS密钥请求费用。费用详情,请参见KMS计费标准

使用OSS完全托管密钥进行加解密(SSE-OSS)

使用OSS完全托管的密钥加密每个Object。为了提升安全性,OSS还会使用主密钥对加密密钥本身进行加密。

仅需要基础的加密能力,对密钥无自管理需求。

无。

免费。

注意事项

  • 在开启了SSE-KMS加密的Bucket中请求上传、下载、访问文件,需确保对指定的CMK ID拥有使用权限,且请求类型不是匿名请求,否则请求失败,并返回This request is forbidden by kms

  • 镜像回源至Bucket中的文件默认不加密。

  • 开启或修改Bucket加密方式不影响Bucket中已有文件的加密配置。

  • 同一个Object在同一时间内仅可以使用一种服务器端加密方式。

  • 如果配置了存储空间加密,仍然可以在上传或拷贝Object时单独对Object配置加密方式,且以Object配置的加密方式为准。更多信息,请参见PutObject

权限说明

RAM用户在不同场景中使用服务端加解密的权限说明如下:

说明

关于为RAM用户授权的具体操作,请参见RAM用户授予自定义的权限策略

  • 设置Bucket加密方式

    • 具有对目标Bucket的管理权限。

    • 具有PutBucketEncryptionGetBucketEncryption权限。

    • 如果设置加密方式为SSE-KMS,且指定了CMK ID,还需要ListKeysListaliasListAliasesByKeyId以及DescribeKey权限。此场景下的RAM Policy授权策略如下:

      {
        "Version": "1",
        "Statement": [
          {
            "Effect": "Allow",
            "Action": [
              "kms:List*",
              "kms:DescribeKey"    
            ],
            "Resource": [
              "acs:kms:*:141661496593****:*" //表示允许调用该阿里云账号ID下所有的KMS密钥,如果仅允许使用某个CMK,此处可输入对应的CMK ID。
            ]
          }
        ]
      }
  • 上传文件至设置了加密方式的Bucket

    • 具有目标Bucket的上传文件权限。

    • 如果设置加密方式为KMS,并指定了CMK ID,还需要ListKeysListAliasesListAliasesByKeyIdDescribeKeyGenerateDataKey以及Decrypt权限。此场景下的RAM Policy授权策略如下:

      {
        "Version": "1",
        "Statement": [
          {
            "Effect": "Allow",
            "Action": [
              "kms:List*",
              "kms:DescribeKey",
              "kms:GenerateDataKey",
              "kms:Decrypt"
            ],
            "Resource": [
              "acs:kms:*:141661496593****:*"//表示允许调用该阿里云账号ID下所有的KMS密钥,如果仅允许使用某个CMK,此处可输入对应的CMK ID。
            ]
          }
        ]
      }
  • 从设置了加密方式的Bucket中下载文件

    • 具有目标Bucket的文件访问权限。

    • 如果设置加密方式为KMS,并指定了CMK ID,还需要Decrypt权限。此场景下的RAM Policy授权策略如下:

      {
        "Version": "1",
        "Statement": [
          {
            "Effect": "Allow",
            "Action": [
              "kms:Decrypt"
            ],
            "Resource": [
              "acs:kms:*:141661496593****:*"//表示具有该阿里云账号ID下所有KMS的解密权限。若要针对某个KMS密钥进行解密,此处可输入对应的CMK ID。
            ]
          }
        ]
      }

操作方式

重要
  • 如果您购买了KMS密钥轮转的增值服务,则服务端加密将支持对KMS密钥进行密钥轮转。开启密钥轮转后,新密钥只对新写入的Object生效,密钥轮转前的存量Object的加密密钥保持不变。

  • 如果您通过OSS更新KMS加密密钥,则新密钥仅适用于新写入的文件加密。更新密钥前写入的存量文件仍使用旧密钥加密。因此,更新密钥后不能删除旧密钥,否则会影响存量文件的正常访问。

使用OSS控制台

方式一:为Bucket开启服务器端加密

创建Bucket时开启服务器端加密功能

  1. 登录OSS管理控制台

  2. 单击Bucket列表,然后单击创建Bucket

  3. 创建Bucket面板,按以下说明填写各项参数。

    其中,服务器端加密区域配置参数说明如下:

    参数

    说明

    服务端加密方式

    选择Object的加密方式。取值范围如下:

    • :不启用服务器端加密。

    • OSS完全托管:使用OSS托管的密钥进行加密。OSS会为每个Object使用不同的密钥进行加密,作为额外的保护,OSS会使用主密钥对加密密钥本身进行加密。

    • KMS:使用KMS默认托管的CMK或指定CMK ID进行加解密操作。

      使用KMS加密方式前,需要开通KMS服务。具体操作,请参见开通密钥管理服务

    加密算法

    可选择AES256SM4加密算法。

    加密密钥

    仅当加密方式选择KMS时,需要配置该选项。

    选择加密密钥。密钥格式为<alias>(CMK ID)。其中<alias>为用户主密钥的别名,CMK ID为用户主密钥ID。取值范围如下:

    • alias/acs/oss(CMK ID):选择该选项后,OSS会使用默认的服务密钥加密Bucket内的数据,并在下载Bucket内的Object时自动进行解密处理。

    • alias/<cmkname>(CMK ID):选择该选项后,OSS会使用指定的服务密钥加密Bucket内的数据,并将加密ObjectCMK ID记录到Object的元数据中,具有解密权限的用户下载Object时会自动解密。其中<cmkname>为创建密钥时配置的主密钥可选标识。

      使用指定的CMK ID前,您需要在KMS管理控制台创建一个与Bucket处于相同地域的普通密钥或外部密钥。具体操作,请参见创建密钥

    其他参数配置详情,请参见创建存储空间

  4. 单击确定

为已创建的Bucket开启服务器端加密

  1. 登录OSS管理控制台

  2. 单击Bucket 列表,然后单击目标Bucket名称。

  3. 在左侧导航栏,选择数据安全 > 服务器端加密

  4. 服务器端加密页面,单击设置,按以下说明配置各项参数。

    参数

    说明

    服务端加密方式

    选择Object的加密方式。取值范围如下:

    • :不启用服务器端加密。

    • OSS完全托管:使用OSS托管的密钥进行加密。OSS会为每个Object使用不同的密钥进行加密,作为额外的保护,OSS会使用主密钥对加密密钥本身进行加密。

    • KMS:使用KMS默认托管的CMK或指定CMK ID进行加解密操作。

      使用KMS加密方式前,需要开通KMS服务。具体操作,请参见开通密钥管理服务

    加密算法

    可选择AES256SM4加密算法。

    加密密钥

    仅当加密方式选择KMS时,需要配置该选项。

    选择加密密钥。密钥格式为<alias>(CMK ID)。其中<alias>为用户主密钥的别名,CMK ID为用户主密钥ID。取值范围如下:

    • OSS默认为您创建服务密钥:选择该选项后,OSS会生成一个默认的服务密钥用于该Bucket的数据加密,并在下载Bucket内的Object时自动进行解密处理。OSS默认创建的服务密钥格式为alias/acs/oss (CMK ID),您可以通过KMS管理控制台查看这一服务密钥。

      说明

      通过KMS管理控制台查看这一服务密钥前,您需要向目标Bucket上传至少一个文件,确保相应的加密密钥被实际创建并关联到您的OSS服务。

    • alias/<cmkname>(CMK ID):选择该选项后,OSS会使用指定的服务密钥加密Bucket内的数据,并将加密ObjectCMK ID记录到Object的元数据中,具有解密权限的用户下载Object时会自动解密。其中<cmkname>为创建密钥时配置的主密钥可选标识。

      使用指定的CMK ID前,您需要在KMS管理控制台创建一个与Bucket处于相同地域的普通密钥或外部密钥。具体操作,请参见创建密钥

  5. 单击保存

方式二:上传文件时设置服务器端加密

具体操作,请参见简单上传

使用阿里云SDK

方式一:为Bucket开启服务器端加密

SDK支持为已创建的Bucket开启服务器端加密,不支持在创建Bucket时开启服务器端加密。以下仅列举常见SDK为已创建的Bucket开启服务器端加密的代码示例。关于其他SDK为已创建的Bucket开启服务器端加密的代码示例,请参见SDK简介

import com.aliyun.oss.*;
import com.aliyun.oss.common.auth.*;
import com.aliyun.oss.common.comm.SignVersion;
import com.aliyun.oss.model.*;

public class Demo {
    public static void main(String[] args) throws Throwable {
        // Endpoint以华东1(杭州)为例,其它Region请按实际情况填写。
        String endpoint = "https://oss-cn-hangzhou.aliyuncs.com";
        // 从环境变量中获取访问凭证。运行本代码示例之前,请确保已设置环境变量OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。
        EnvironmentVariableCredentialsProvider credentialsProvider = CredentialsProviderFactory.newEnvironmentVariableCredentialsProvider();
        // 填写Bucket名称,例如examplebucket。
        String bucketName = "examplebucket";
        // 填写Bucket所在地域。以华东1(杭州)为例,Region填写为cn-hangzhou。
        String region = "cn-hangzhou";

        // 创建OSSClient实例。
        // 当OSSClient实例不再使用时,调用shutdown方法以释放资源。
        ClientBuilderConfiguration clientBuilderConfiguration = new ClientBuilderConfiguration();
        clientBuilderConfiguration.setSignatureVersion(SignVersion.V4);        
        OSS ossClient = OSSClientBuilder.create()
        .endpoint(endpoint)
        .credentialsProvider(credentialsProvider)
        .clientConfiguration(clientBuilderConfiguration)
        .region(region)               
        .build();

        try {
            // 以设置Bucket加密方式为SM4为例。如果是AES256加密,请替换为SSEAlgorithm.AES256。
            ServerSideEncryptionByDefault applyServerSideEncryptionByDefault = new ServerSideEncryptionByDefault(SSEAlgorithm.SM4);
            ServerSideEncryptionConfiguration sseConfig = new ServerSideEncryptionConfiguration();
            sseConfig.setApplyServerSideEncryptionByDefault(applyServerSideEncryptionByDefault);
            SetBucketEncryptionRequest request = new SetBucketEncryptionRequest(bucketName, sseConfig);
            ossClient.setBucketEncryption(request);
        } catch (OSSException oe) {
            System.out.println("Caught an OSSException, which means your request made it to OSS, "
                    + "but was rejected with an error response for some reason.");
            System.out.println("Error Message:" + oe.getErrorMessage());
            System.out.println("Error Code:" + oe.getErrorCode());
            System.out.println("Request ID:" + oe.getRequestId());
            System.out.println("Host ID:" + oe.getHostId());
        } catch (ClientException ce) {
            System.out.println("Caught an ClientException, which means the client encountered "
                    + "a serious internal problem while trying to communicate with OSS, "
                    + "such as not being able to access the network.");
            System.out.println("Error Message:" + ce.getMessage());
        } finally {
            if (ossClient != null) {
                ossClient.shutdown();
            }
        }
    }
}
<?php

// 引入自动加载文件 加载依赖库
require_once __DIR__ . '/../vendor/autoload.php';

use AlibabaCloud\Oss\V2 as Oss;

// 定义命令行参数描述
$optsdesc = [
    "region" => ['help' => 'The region in which the bucket is located', 'required' => True], // 区域是必填项 存储空间所在的区域
    "endpoint" => ['help' => 'The domain names that other services can use to access OSS', 'required' => False], // 终端节点是可选项 其他服务可以用来访问OSS的域名
    "bucket" => ['help' => 'The name of the bucket', 'required' => True], // 存储空间名称是必填项
];

// 生成长选项列表 用于解析命令行参数
$longopts = \array_map(function ($key) {
    return "$key:"; // 每个参数后面加冒号 表示需要值
}, array_keys($optsdesc));

// 解析命令行参数
$options = getopt("", $longopts); 

// 检查必填参数是否缺失
foreach ($optsdesc as $key => $value) {
    if ($value['required'] === True && empty($options[$key])) {
        $help = $value['help'];
        echo "Error: the following arguments are required: --$key, $help"; // 提示用户缺少必填参数
        exit(1); 
    }
}

// 获取命令行参数值
$region = $options["region"]; // 存储空间所在区域
$bucket = $options["bucket"]; // 存储空间名称

// 使用环境变量加载凭证信息 AccessKeyId 和 AccessKeySecret
$credentialsProvider = new Oss\Credentials\EnvironmentVariableCredentialsProvider();

// 使用SDK的默认配置
$cfg = Oss\Config::loadDefault();

// 设置凭证提供者
$cfg->setCredentialsProvider($credentialsProvider);

// 设置区域
$cfg->setRegion($region);

// 如果提供了终端节点 则设置终端节点
if (isset($options["endpoint"])) {
    $cfg->setEndpoint($options["endpoint"]);
}

// 创建OSS客户端实例
$client = new Oss\Client($cfg);

// 创建设置存储空间加密配置的请求对象 使用KMS加密算法并指定数据加密方式为SM4
$request = new Oss\Models\PutBucketEncryptionRequest(
    bucket: $bucket, 
    serverSideEncryptionRule: new Oss\Models\ServerSideEncryptionRule(
        applyServerSideEncryptionByDefault: new Oss\Models\ApplyServerSideEncryptionByDefault(
            sseAlgorithm: 'KMS', // 使用KMS加密算法
            kmsDataEncryption: 'SM4' // 数据加密方式为SM4
    ))
);

// 调用putBucketEncryption方法设置存储空间的加密配置
$result = $client->putBucketEncryption($request);

// 打印返回结果
printf(
    'status code:' . $result->statusCode . PHP_EOL . // HTTP响应状态码
    'request id:' . $result->requestId // 请求的唯一标识
);
const OSS = require("ali-oss");

const client = new OSS({
  // yourregion填写Bucket所在地域。以华东1(杭州)为例,Region填写为oss-cn-hangzhou。
  region: 'yourregion',
  // 从环境变量中获取访问凭证。运行本代码示例之前,请确保已设置环境变量OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。
  accessKeyId: process.env.OSS_ACCESS_KEY_ID,
  accessKeySecret: process.env.OSS_ACCESS_KEY_SECRET,
  authorizationV4: true,
  // yourbucketname填写存储空间名称。
  bucket: 'yourbucketname'
});

async function putBucketEncryption() {
  try {
    // 配置Bucket加密方式。    

    const result = await client.putBucketEncryption("bucket-name", {
      SSEAlgorithm: "AES256", // 此处以设置AES256加密为例。若使用KMS加密,需添加KMSMasterKeyID属性。
      // KMSMasterKeyID:“yourKMSMasterKeyId”,设置KMS密钥ID,加密方式为KMS可设置此项。当SSEAlgorithm值为KMS,且使用指定的密钥加密时,需输入密钥ID。其他情况下,必须为空。
    });
    console.log(result);
  } catch (e) {
    console.log(e);
  }
}

putBucketEncryption();
import argparse
import alibabacloud_oss_v2 as oss

# 创建命令行参数解析器,用于接收用户输入的参数
parser = argparse.ArgumentParser(description="put bucket encryption sample")

# 添加命令行参数 --region,表示存储空间所在的地域,必填项
parser.add_argument('--region', help='The region in which the bucket is located.', required=True)

# 添加命令行参数 --bucket,表示存储空间的名称,必填项
parser.add_argument('--bucket', help='The name of the bucket.', required=True)

# 添加命令行参数 --endpoint,表示其他服务访问 OSS 时使用的域名,可选项
parser.add_argument('--endpoint', help='The domain names that other services can use to access OSS')

# 添加命令行参数 --sse_algorithm,表示默认的服务器端加密方法,默认值为 'KMS'
# 有效值:KMS(使用 KMS 加密)、AES256(使用 AES-256 加密)、SM4(使用国密算法 SM4)
parser.add_argument('--sse_algorithm', help='The default server-side encryption method. Valid values: KMS, AES256, and SM4.', default='KMS')

# 添加命令行参数 --kms_master_key_id,表示当 SSEAlgorithm 设置为 KMS 且使用指定的 CMK 时的主密钥 ID
# 如果不使用指定的 CMK,则留空
parser.add_argument('--kms_master_key_id', help='The CMK ID that is specified when SSEAlgorithm is set to KMS and a specified CMK is used for encryption. In other cases, leave this parameter empty.', default='')

# 添加命令行参数 --kms_data_encryption,表示对象加密时使用的算法
# 默认值为 'SM4',仅在 SSEAlgorithm 设置为 KMS 时有效
parser.add_argument('--kms_data_encryption', help='The algorithm that is used to encrypt objects. If this parameter is not specified, objects are encrypted by using AES256. This parameter is valid only when SSEAlgorithm is set to KMS. Valid value: SM4', default='SM4')

def main():
    # 解析命令行参数
    args = parser.parse_args()

    # 从环境变量中加载凭证信息(AccessKeyId 和 AccessKeySecret)
    credentials_provider = oss.credentials.EnvironmentVariableCredentialsProvider()

    # 加载 SDK 的默认配置
    cfg = oss.config.load_default()

    # 设置凭证提供者
    cfg.credentials_provider = credentials_provider

    # 设置存储空间所在的地域
    cfg.region = args.region

    # 如果用户提供了自定义的 endpoint,则设置到配置中
    if args.endpoint is not None:
        cfg.endpoint = args.endpoint

    # 使用配置对象初始化 OSS 客户端
    client = oss.Client(cfg)

    # 调用 put_bucket_encryption 方法设置存储空间的加密配置
    result = client.put_bucket_encryption(
        oss.PutBucketEncryptionRequest(
            bucket=args.bucket,  # 指定目标存储空间的名称
            server_side_encryption_rule=oss.ServerSideEncryptionRule(
                apply_server_side_encryption_by_default=oss.ApplyServerSideEncryptionByDefault(
                    kms_master_key_id=args.kms_master_key_id,  # 主密钥 ID(仅在 SSEAlgorithm 为 KMS 时有效)
                    kms_data_encryption=args.kms_data_encryption,  # 对象加密算法(仅在 SSEAlgorithm 为 KMS 时有效)
                    sse_algorithm=args.sse_algorithm,  # 服务器端加密算法(如 KMS、AES256 或 SM4)
                ),
            ),
        )
    )

    # 打印操作结果的状态码和请求 ID
    print(f'status code: {result.status_code}, '  # HTTP 状态码,表示请求是否成功
          f'request id: {result.request_id}')     # 请求 ID,用于追踪请求日志和调试


if __name__ == "__main__":
    # 程序入口,调用 main 函数执行逻辑
    main()
using Aliyun.OSS;
using Aliyun.OSS.Common;
// yourEndpoint填写Bucket所在地域对应的Endpoint。以华东1(杭州)为例,Endpoint填写为https://oss-cn-hangzhou.aliyuncs.com。
var endpoint = "yourEndpoint";
// 从环境变量中获取访问凭证。运行本代码示例之前,请确保已设置环境变量OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。
var accessKeyId = Environment.GetEnvironmentVariable("OSS_ACCESS_KEY_ID");
var accessKeySecret = Environment.GetEnvironmentVariable("OSS_ACCESS_KEY_SECRET");
// 填写Bucket名称,例如examplebucket。
var bucketName = "examplebucket";
// 填写Bucket所在地域对应的Region。以华东1(杭州)为例,Region填写为cn-hangzhou。
const string region = "cn-hangzhou";

// 创建ClientConfiguration实例,按照您的需要修改默认参数。
var conf = new ClientConfiguration();

// 设置v4签名。
conf.SignatureVersion = SignatureVersion.V4;

// 创建OssClient实例。
var client = new OssClient(endpoint, accessKeyId, accessKeySecret, conf);
client.SetRegion(region);
try
{
    // 配置Bucket加密。
    var request = new SetBucketEncryptionRequest(bucketName, "KMS", null);
    client.SetBucketEncryption(request);
    Console.WriteLine("Set bucket:{0} Encryption succeeded ", bucketName);
}
catch (OssException ex)
{
    Console.WriteLine("Failed with error code: {0}; Error info: {1}. \nRequestID:{2}\tHostID:{3}",
        ex.ErrorCode, ex.Message, ex.RequestId, ex.HostId);
}
catch (Exception ex)
{
    Console.WriteLine("Failed with error info: {0}", ex.Message);
}
package main

import (
	"log"

	"github.com/aliyun/aliyun-oss-go-sdk/oss"
)

func main() {
	// 从环境变量中获取访问凭证。运行本代码示例之前,请确保已设置环境变量OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。
	provider, err := oss.NewEnvironmentVariableCredentialsProvider()
	if err != nil {
		log.Fatalf("Error creating credentials provider: %v", err)
	}

	// 创建OSSClient实例。
	// yourEndpoint填写Bucket对应的Endpoint,以华东1(杭州)为例,填写为https://oss-cn-hangzhou.aliyuncs.com。其它Region请按实际情况填写。
	// yourRegion填写Bucket所在地域,以华东1(杭州)为例,填写为cn-hangzhou。其它Region请按实际情况填写。
	clientOptions := []oss.ClientOption{oss.SetCredentialsProvider(&provider)}
	clientOptions = append(clientOptions, oss.Region("yourRegion"))
	// 设置签名版本
	clientOptions = append(clientOptions, oss.AuthVersion(oss.AuthV4))
	client, err := oss.New("yourEndpoint", "", "", clientOptions...)
	if err != nil {
		log.Fatalf("Error creating OSS client: %v", err)
	}

	// 初始化一个加密规则,加密方式以AES256为例。
	config := oss.ServerEncryptionRule{
		SSEDefault: oss.SSEDefaultRule{
			SSEAlgorithm: "AES256",
		},
	}

	// 设置Bucket的加密规则。
	err = client.SetBucketEncryption("yourBucketName", config)
	if err != nil {
		log.Fatalf("Error setting bucket encryption: %v", err)
	}

	log.Println("Bucket encryption set successfully")
}
#include <alibabacloud/oss/OssClient.h>
using namespace AlibabaCloud::OSS;

int main(void)
{
    /* 初始化OSS账号信息。*/
            
    /* yourEndpoint填写Bucket所在地域对应的Endpoint。以华东1(杭州)为例,Endpoint填写为https://oss-cn-hangzhou.aliyuncs.com。*/
    std::string Endpoint = "yourEndpoint";
    /* yourRegion填写Bucket所在地域对应的Region。以华东1(杭州)为例,Region填写为cn-hangzhou。*/
    std::string Region = "yourRegion";
    /* 填写Bucket名称,例如examplebucket。*/
    std::string BucketName = "examplebucket";

    /* 初始化网络等资源。*/
    InitializeSdk();

    ClientConfiguration conf;
    conf.signatureVersion = SignatureVersionType::V4;
    /* 从环境变量中获取访问凭证。运行本代码示例之前,请确保已设置环境变量OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。*/
    auto credentialsProvider = std::make_shared<EnvironmentVariableCredentialsProvider>();
    OssClient client(Endpoint, credentialsProvider, conf);
    client.SetRegion(Region);

    SetBucketEncryptionRequest setrequest(BucketName);
    setrequest.setSSEAlgorithm(SSEAlgorithm::KMS);
    /* 设置KMS服务端加密。*/
    auto outcome = client.SetBucketEncryption(setrequest);

    if (!outcome.isSuccess()) {
        /* 异常处理。*/
        std::cout << "SetBucketEncryption fail" <<
        ",code:" << outcome.error().Code() <<
        ",message:" << outcome.error().Message() <<
        ",requestId:" << outcome.error().RequestId() << std::endl;
        return -1;
    }

    /* 释放网络等资源。*/
    ShutdownSdk();
    return 0;
}

方式二:上传文件时设置服务器端加密

以下仅列举常见SDK上传文件时设置服务器端加密的代码示例。关于其他SDK上传文件时设置服务器端加密的代码示例,请参见SDK简介

Java

import com.aliyun.oss.*;
import com.aliyun.oss.common.auth.*;
import com.aliyun.oss.common.comm.SignVersion;
import com.aliyun.oss.internal.OSSHeaders;
import com.aliyun.oss.model.PutObjectRequest;
import com.aliyun.oss.model.PutObjectResult;
import com.aliyun.oss.model.ObjectMetadata;
import java.io.File;

public class Put {
    public static void main(String[] args) throws Exception {
        // Endpoint以华东1(杭州)为例,其它Region请按实际情况填写。
        String endpoint = "https://oss-cn-hangzhou.aliyuncs.com";
        // 填写Endpoint对应的Region信息,例如cn-hangzhou。
        String region = "cn-hangzhou";
        // 从环境变量中获取访问凭证。运行本代码示例之前,请确保已设置环境变量OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。
        EnvironmentVariableCredentialsProvider credentialsProvider = CredentialsProviderFactory.newEnvironmentVariableCredentialsProvider();
        // 填写Bucket名称,例如examplebucket。
        String bucketName = "examplebucket";
        // 填写Object完整路径,完整路径中不能包含Bucket名称,例如exampledir/exampleobject.txt。
        String objectName = "exampledir/exampleobject.txt";
        // 填写本地文件的完整路径,例如D:\\localpath\\examplefile.txt。
        // 如果未指定本地路径,则默认从示例程序所属项目对应本地路径中上传文件。
        String filePath= "D:\\localpath\\examplefile.txt";
        
        // 创建OSSClient实例。
        // 当OSSClient实例不再使用时,调用shutdown方法以释放资源。
        ClientBuilderConfiguration clientBuilderConfiguration = new ClientBuilderConfiguration();
        // 显式声明使用 V4 签名算法
        clientBuilderConfiguration.setSignatureVersion(SignVersion.V4);
        OSS ossClient = OSSClientBuilder.create()
                .endpoint(endpoint)
                .credentialsProvider(credentialsProvider)
                .clientConfiguration(clientBuilderConfiguration)
                .region(region)
                .build();
                
        try {
            // 创建ObjectMetadata对象,并设置服务器端加密方式为AES256。
            ObjectMetadata metadata = new ObjectMetadata();
            metadata.setHeader(OSSHeaders.OSS_SERVER_SIDE_ENCRYPTION, "AES256");

            // 创建PutObjectRequest对象。
            PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, objectName, new File(filePath));
            putObjectRequest.setMetadata(metadata); 

            // 上传文件。
            PutObjectResult result = ossClient.putObject(putObjectRequest);
        } catch (OSSException oe) {
            System.out.println("Caught an OSSException, which means your request made it to OSS, "
                    + "but was rejected with an error response for some reason.");
            System.out.println("Error Message:" + oe.getErrorMessage());
            System.out.println("Error Code:" + oe.getErrorCode());
            System.out.println("Request ID:" + oe.getRequestId());
            System.out.println("Host ID:" + oe.getHostId());
        } catch (ClientException ce) {
            System.out.println("Caught an ClientException, which means the client encountered "
                    + "a serious internal problem while trying to communicate with OSS, "
                    + "such as not being able to access the network.");
            System.out.println("Error Message:" + ce.getMessage());
        } finally {
            if (ossClient != null) {
                ossClient.shutdown();
            }
        }
    }
}

PHP

<?php
if (is_file(__DIR__ . '/../autoload.php')) {
    require_once __DIR__ . '/../autoload.php';
}
if (is_file(__DIR__ . '/../vendor/autoload.php')) {
    require_once __DIR__ . '/../vendor/autoload.php';
}

use OSS\Credentials\EnvironmentVariableCredentialsProvider;
use OSS\OssClient;
use OSS\Core\OssException;


// 从环境变量中获取访问凭证。运行本代码示例之前,请确保已设置环境变量OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。
$provider = new EnvironmentVariableCredentialsProvider();
// yourEndpoint填写Bucket所在地域对应的Endpoint。以华东1(杭州)为例,Endpoint填写为https://oss-cn-hangzhou.aliyuncs.com。
$endpoint = "https://oss-cn-hangzhou.aliyuncs.com";
// 填写Bucket名称,例如examplebucket。
$bucket= "examplebucket";
// 填写Object完整路径,例如exampledir/exampleobject.txt。Object完整路径中不能包含Bucket名称。
$object = "exampledir/exampleobject.txt";
// 填写本地文件的完整路径,例如D:\\localpath\\examplefile.txt。如果未指定本地路径,则默认从示例程序所属项目对应本地路径中上传文件。
$filePath = "D:\\localpath\\examplefile.txt";

try{
    $config = array(
        "provider" => $provider,
        "endpoint" => $endpoint,
    );
    $ossClient = new OssClient($config);

    $options[OssClient::OSS_HEADERS] = array(
         // 设置服务器端加密方式为AES256。
        "x-oss-server-side-encryption"=>"AES256",
    );
    // 调用uploadFile方法上传文件,并传入UploadOptions对象。
    $ossClient->uploadFile($bucket, $object, $filePath, $options);
} catch(OssException $e) {
    printf(__FUNCTION__ . ": FAILED\n");
    printf($e->getMessage() . "\n");
    return;
}
print(__FUNCTION__ . "OK" . "\n");

Node.js

const OSS = require("ali-oss");
const path = require("path");

const client = new OSS({
  // yourregion填写Bucket所在地域。以华东1(杭州)为例,Region填写为oss-cn-hangzhou。
  region: "oss-cn-hangzhou",
  // 从环境变量中获取访问凭证。运行本代码示例之前,请确保已设置环境变量OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。
  accessKeyId: process.env.OSS_ACCESS_KEY_ID,
  accessKeySecret: process.env.OSS_ACCESS_KEY_SECRET,
  // 填写Bucket名称。
  bucket: "examplebucket",
});

const headers = {
  // 设置服务器端加密方式为AES256。
  "x-oss-server-side-encryption": "AES256",
};

async function put() {
  try {。
    const result = await client.put(
      // 填写Object完整路径,例如exampledir/exampleobject.txt。Object完整路径中不能包含Bucket名称。
      "exampledir/exampleobject.txt",
      // 填写本地文件的完整路径,例如D:\\localpath\\examplefile.txt。如果未指定本地路径,则默认从示例程序所属项目对应本地路径中上传文件。
      path.normalize("D:\\examplefile.jpg"),
      { headers }
    );
    console.log(result);
  } catch (e) {
    console.log(e);
  }
}

put();

Python

# -*- coding: utf-8 -*-
import oss2
import os
from oss2.credentials import EnvironmentVariableCredentialsProvider

# 从环境变量中获取访问凭证。运行本代码示例之前,请确保已设置环境变量OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。
auth = oss2.ProviderAuth(EnvironmentVariableCredentialsProvider())

# yourEndpoint填写Bucket所在地域对应的Endpoint。以华东1(杭州)为例,Endpoint填写为https://oss-cn-hangzhou.aliyuncs.com。
endpoint = 'https://oss-cn-hangzhou.aliyuncs.com'

# 填写Bucket名称。
bucket_name = 'examplebucket0703'
bucket = oss2.Bucket(auth, endpoint, bucket_name)

# 必须以二进制的方式打开文件。
# 填写本地文件的完整路径。如果未指定本地路径,则默认从示例程序所属项目对应本地路径中上传文件。
local_file_path = 'D:\\examplefile.jpg'
with open(local_file_path, 'rb') as fileobj:
    # Seek方法用于指定从第1000个字节位置开始读写。上传时会从您指定的第1000个字节位置开始上传,直到文件结束。
    fileobj.seek(1000, os.SEEK_SET)
    # Tell方法用于返回当前位置。
    current = fileobj.tell()

    # 设置服务器端加密方式为AES256。
    headers = {
        'x-oss-server-side-encryption': 'AES256',
    }

    # 填写Object完整路径。Object完整路径中不能包含Bucket名称。
    object_key = 'exampledir/object1.jpg'
    bucket.put_object(object_key, fileobj, headers=headers)

Go

package main

import (
	"fmt"
	"github.com/aliyun/aliyun-oss-go-sdk/oss"
	"os"
)

func main() {
	// 从环境变量中获取访问凭证。运行本代码示例之前,请确保已设置环境变量OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。
	provider, err := oss.NewEnvironmentVariableCredentialsProvider()
	if err != nil {
		fmt.Println("Error:", err)
		os.Exit(-1)
	}

	// 创建OSSClient实例。
	// yourEndpoint填写Bucket对应的Endpoint,以华东1(杭州)为例,填写为https://oss-cn-hangzhou.aliyuncs.com。其它Region请按实际情况填写。
	client, err := oss.New("https://oss-cn-hangzhou.aliyuncs.com", "", "", oss.SetCredentialsProvider(&provider))
	if err != nil {
		fmt.Println("Error:", err)
		os.Exit(-1)
	}

	// 填写存储空间名称,例如examplebucket。
	bucket, err := client.Bucket("examplebucket")
	if err != nil {
		fmt.Println("Error:", err)
		os.Exit(-1)
	}
  // 填写Object完整路径,例如exampledir/exampleobject.txt。Object完整路径中不能包含Bucket名称。
  // 填写本地文件的完整路径,例如D:\\localpath\\examplefile.txt。如果未指定本地路径,则默认从示例程序所属项目对应本地路径中上传文件。
  // 设置服务器端加密方式为AES256。
	err = bucket.PutObjectFromFile("D:\\localpath\\examplefile.txt", "D:\\examplefile.jpg", oss.ServerSideEncryption("AES256"))
	if err != nil {
		fmt.Println("Error:", err)
		os.Exit(-1)
	}
}

使用命令行工具ossutil

方式一:为Bucket开启服务器端加密

您可以使用命令行工具ossutil来为Bucket开启服务器端加密,ossutil的安装请参见安装ossutil

以下示例展示了如何为已创建的存储空间examplebucket 设置服务端加密方式为AES256。

ossutil api put-bucket-encryption --bucket examplebucket --server-side-encryption-rule "{\"ApplyServerSideEncryptionByDefault\":{\"SSEAlgorithm\":\"AES256\"}}"

如果您想了解该命令的更多信息,请参见put-bucket-encryption

方式二:上传文件时设置服务器端加密

ossutil支持在上传文件时指定文件的服务器端加密方式,ossutil的安装请参见安装ossutil。以下示例展示了如何在上传文件并设定服务端加密方式为AES256。

ossutil cp examplefile.txt oss://examplebucket --metadata=x-oss-server-side-encryption:AES256

如果您想了解该命令的更多信息,请参见cp(上传文件)

使用KMS托管密钥进行加解密

使用KMS托管的用户主密钥CMK生成加密密钥加密数据,通过信封加密机制,可进一步防止未经授权的数据访问。借助KMS,您可以专注于数据加解密、电子签名验签等业务功能,无需花费大量成本来保障密钥的保密性、完整性和可用性。

SSE-KMS加密方式的逻辑示意图如下。

image

使用SSE-KMS加密方式时,可使用如下密钥:

  • 使用OSS默认托管的KMS密钥

    OSS使用默认托管的KMS CMK生成不同的密钥来加密不同的Object,并且在Object被下载时自动解密。首次使用时,OSS会在KMS平台创建一个OSS托管的CMK。

    配置方式如下:

    • 配置Bucket加密方式

      配置Bucket加密方式为KMS,指定加密算法为AES256SM4,但不指定具体的CMK ID。此后,所有上传至此BucketObject都会被加密。

    • 为目标Object配置加密方式

      上传Object或修改Objectmeta信息时,在请求中携带x-oss-server-side-encryption参数,并设置参数值为KMS。此时,OSS将使用默认托管的KMS CMK,并通过AES256加密算法加密Object。如需修改加密算法为SM4,您还需增加x-oss-server-side-data-encryption参数,并设置参数值为SM4更多信息,请参见PutObject

  • 使用自带密钥BYOK(Bring Your Own Key)

    您在KMS控制台使用BYOK材料生成CMK后,OSS可使用指定的KMS CMK生成不同的密钥来加密不同的Object,并将加密ObjectCMK ID记录到Object的元数据中,只有具有解密权限的用户下载Object时才会自动解密。

    BYOK材料来源有两种:

    • 由阿里云提供的BYOK材料:在KMS平台创建密钥时,选择密钥材料来源为阿里云KMS

    • 使用用户自有的BYOK材料:在KMS平台创建密钥时,选择密钥材料来源为外部,并按照要求导入外部密钥材料。关于导入外部密钥的具体操作,请参见导入密钥材料

    配置方式如下:

    • 配置Bucket加密方式

      配置Bucket加密方式为KMS,指定加密算法为AES256SM4,并指定具体的CMK ID。此后,所有上传至此BucketObject都会被加密。

    • 为目标Object配置加密方式

      上传Object或修改Objectmeta信息时,在请求中携带x-oss-server-side-encryption参数,并设置参数值为KMS;携带x-oss-server-side-encryption-key-id参数,并设置参数值为指定CMK ID。此时,OSS将使用指定的KMS CMK,并通过AES256加密算法加密Object。如需修改加密算法,您还需增加x-oss-server-side-data-encryption参数,并设置参数值为SM4更多信息,请参见PutObject

使用OSS完全托管密钥进行加解密

OSS负责生成和管理数据加密密钥,并采用高强度、多因素的安全措施进行保护。数据加密的算法采用行业标准的AES256(即256位高级加密标准)和国密SM4算法。

配置方式如下:

  • 配置Bucket加密方式

    配置Bucket加密方式为OSS完全托管,并指定加密算法为AES256SM4。此后,所有上传至此BucketObject都会默认被加密。

  • 为目标Object配置加密方式

    上传Object或修改Objectmeta信息时,在请求中携带x-oss-server-side-encryption参数,并设置参数值为AES256SM4。此时,OSS将使用OSS完全托管的密钥加密Object。更多信息,请参见PutObject

相关API

以上操作方式底层基于API实现,如果您的程序自定义要求较高,您可以直接发起REST API请求。直接发起REST API请求需要手动编写代码计算签名。更多信息,请参见PutBucketEncryption

常见问题

配置Bucket加密方式后,OSS会对历史文件进行加密吗?

OSS只对服务器端加密配置生效后上传的Object进行加密,不会加密历史文件。如果您需要加密历史文件,可通过CopyObject覆写历史文件。

    OSZAR »