服务器端加密

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

说明

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

使用场景

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

注意事项

  • 华东1(杭州)、华东2(上海)、华北1(青岛)、华北2(北京)、华北 3(张家口)、华北5(呼和浩特)、华北6(乌兰察布)、华南1(深圳)、华南2(河源)、华南3(广州)、西南1(成都)、中国香港、美国(硅谷)、美国(弗吉尼亚)、日本(东京)、韩国(首尔)、新加坡、马来西亚(吉隆坡)、印度尼西亚(雅加达)、菲律宾(马尼拉)、泰国(曼谷)、德国(法兰克福)、英国(伦敦)、阿联酋(迪拜)地域支持开启服务器端加密。

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

  • 无地域属性存储空间仅支持SSE-OSS加密方式,不支持SSE-KMS加密方式。

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

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

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

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

加密方式

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还会使用主密钥对加密密钥本身进行加密。

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

无。

免费。

操作步骤

使用OSS控制台

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

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

  1. 登录OSS管理控制台

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

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

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

    参数

    说明

    服务端加密方式

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

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

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

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

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

    加密算法

    可选择AES256或SM4加密算法。

    加密密钥

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

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

    • alias/acs/oss(CMK ID):使用默认托管的CMK生成不同的密钥来加密不同的Object,并且在Object被下载时自动解密。

    • alias/<cmkname>(CMK ID):使用指定的CMK生成不同的密钥来加密不同的Object,并将加密Object的CMK 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服务。具体操作,请参见开通密钥管理服务

    加密算法

    可选择AES256或SM4加密算法。

    加密密钥

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

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

    • alias/acs/oss(CMK ID):使用默认托管的CMK生成不同的密钥来加密不同的Object,并且在Object被下载时自动解密。

    • alias/<cmkname>(CMK ID):使用指定的CMK生成不同的密钥来加密不同的Object,并将加密Object的CMK 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.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实例。
        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
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;
use OSS\Model\ServerSideEncryptionConfig;

// 从环境变量中获取访问凭证。运行本代码示例之前,请确保已设置环境变量OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。 
$provider = new EnvironmentVariableCredentialsProvider();
// Endpoint以杭州为例,其它Region请按实际情况填写。
$endpoint = "https://oss-cn-hangzhou.aliyuncs.com";
$bucket= "<yourBucketName>";

$config = array(
        "provider" => $provider,
        "endpoint" => $endpoint,
        "signatureVersion" => OssClient::OSS_SIGNATURE_VERSION_V4,
        "region"=> "cn-hangzhou"
    );
    $ossClient = new OssClient($config);

try {
    // 将Bucket默认的服务器端加密方式设置为OSS完全托管加密(SSE-OSS)。
    $config = new ServerSideEncryptionConfig("AES256");
    $ossClient->putBucketEncryption($bucket, $config);

    // 将Bucket默认的服务器端加密方式设置为KMS,且不指定CMK ID。
    $config = new ServerSideEncryptionConfig("KMS");
    $ossClient->putBucketEncryption($bucket, $config);

    // 将Bucket默认的服务器端加密方式设置为KMS,且指定了CMK ID。
    $config = new ServerSideEncryptionConfig("KMS", "your kms id");
    $ossClient->putBucketEncryption($bucket, $config);
} catch (OssException $e) {
    printf(__FUNCTION__ . ": FAILED\n");
    printf($e->getMessage() . "\n");
    return;
}

print(__FUNCTION__ . ": OK" . "\n"); 
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();
# -*- coding: utf-8 -*-
import oss2
from oss2.credentials import EnvironmentVariableCredentialsProvider
from oss2.models import ServerSideEncryptionRule
# 从环境变量中获取访问凭证。运行本代码示例之前,请确保已设置环境变量OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。
auth = oss2.ProviderAuthV4(EnvironmentVariableCredentialsProvider())

# 填写Bucket所在地域对应的Endpoint。以华东1(杭州)为例,Endpoint填写为https://oss-cn-hangzhou.aliyuncs.com。
endpoint = "https://oss-cn-hangzhou.aliyuncs.com"
# 填写Endpoint对应的Region信息,例如cn-hangzhou。注意,v4签名下,必须填写该参数
region = "cn-hangzhou"

# examplebucket填写存储空间名称。
bucket = oss2.Bucket(auth, endpoint, "examplebucket", region=region)

# 创建Bucket加密配置,以AES256加密为例。
rule = ServerSideEncryptionRule()
rule.sse_algorithm = oss2.SERVER_SIDE_ENCRYPTION_AES256
# 设置KMS密钥ID,加密方式为KMS可设置此项。如需使用指定的密钥加密,需输入指定的CMK ID;若使用OSS托管的CMK进行加密,此项为空。使用AES256进行加密时,此项必须为空。
rule.kms_master_keyid = ""

# 设置Bucket加密。
result = bucket.put_bucket_encryption(rule)

# 查看HTTP返回码。
print('http response code:', result.status)
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";
// 创建OSSClient实例。
var client = new OssClient(endpoint, accessKeyId, accessKeySecret);
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.ClientException;
import com.aliyun.oss.OSS;
import com.aliyun.oss.common.auth.*;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.OSSException;
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";
        // 从环境变量中获取访问凭证。运行本代码示例之前,请确保已设置环境变量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实例。
        OSS ossClient = new OSSClientBuilder().build(endpoint, credentialsProvider);
        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开启服务器端加密,不支持在创建Bucket时开启服务器端加密。

为已创建的Bucket开启服务器端加密的具体操作,请参见bucket-encryption(服务器端加密)

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

ossutil支持在上传文件时指定文件的服务器端加密方式。具体操作,请参见上传并指定加密方式

使用REST API

如果您的程序自定义要求较高,您可以直接发起REST API请求。直接发起REST API请求需要手动编写代码计算签名。

  • REST API支持为已创建的Bucket开启服务器端加密,不支持在创建Bucket时开启服务器端加密。

    为已创建的Bucket开启服务器端加密的更多信息,请参见PutBucketEncryption

  • REST API支持在上传文件时指定文件的服务器端加密方式。更多信息,请参见PutObject

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

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

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

image

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

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

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

    配置方式如下:

    • 配置Bucket加密方式

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

    • 为目标Object配置加密方式

      上传Object或修改Object的meta信息时,在请求中携带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,并将加密Object的CMK ID记录到Object的元数据中,只有具有解密权限的用户下载Object时才会自动解密。

    BYOK材料来源有两种:

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

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

    配置方式如下:

    • 配置Bucket加密方式

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

    • 为目标Object配置加密方式

      上传Object或修改Object的meta信息时,在请求中携带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完全托管,并指定加密算法为AES256或SM4。此后,所有上传至此Bucket的Object都会默认被加密。

  • 为目标Object配置加密方式

    上传Object或修改Object的meta信息时,在请求中携带x-oss-server-side-encryption参数,并设置参数值为AES256SM4。此时,OSS将使用OSS完全托管的密钥加密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。
            ]
          }
        ]
      }

常见问题

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

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