说明
关于响应头中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 服务端进行加解密。
因安全合规的要求,需要使用自管理、可指定的密钥。
在 KMS 服务侧产生少量的 KMS 密钥请求费用。费用详情,请参见KMS 计费标准 。
使用 OSS 完全托管密钥进行加解密(SSE-OSS)
使用 OSS 完全托管的密钥加密每个 Object。为了提升安全性,OSS 还会使用主密钥对加密密钥本身进行加密。
仅需要基础的加密能力,对密钥无自管理需求。
无。
免费。
操作步骤
使用 OSS 控制台
方式一:为 Bucket 开启服务器端加密
创建Bucket时开启服务器端加密功能
为已创建的Bucket开启服务器端加密
登录OSS 管理控制台 。
单击Bucket 列表 ,然后单击创建 Bucket 。
在创建 Bucket 面板,按以下说明填写各项参数。
其中,服务器端加密 区域配置参数说明如下:
参数
说明
服务端加密方式
选择 Object 的加密方式。取值范围如下:
无 :不启用服务器端加密。
OSS 完全托管 :使用 OSS 托管的密钥进行加密。OSS 会为每个 Object 使用不同的密钥进行加密,作为额外的保护,OSS 会使用主密钥对加密密钥本身进行加密。
KMS :使用 KMS 默认托管的 CMK 或指定 CMK ID 进行加解密操作。
使用 KMS 加密方式前,需要开通 KMS 服务。具体操作,请参见开通密钥管理服务 。
加密算法
可选择 AES256 或 SM4 加密算法。 仅支持 AES256 加密算法。
加密密钥
仅当加密方式 选择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 处于相同地域的普通密钥或外部密钥。具体操作,请参见创建密钥 。
其他参数配置详情,请参见创建存储空间 。
单击确定 。
登录OSS 管理控制台 。
单击Bucket 列表 ,然后单击目标 Bucket 名称。
在左侧导航栏,选择。
在服务器端加密 页面,单击设置 ,按以下说明配置各项参数。
参数
说明
服务端加密方式
选择 Object 的加密方式。取值范围如下:
无 :不启用服务器端加密。
OSS 完全托管 :使用 OSS 托管的密钥进行加密。OSS 会为每个 Object 使用不同的密钥进行加密,作为额外的保护,OSS 会使用主密钥对加密密钥本身进行加密。
KMS :使用 KMS 默认托管的 CMK 或指定 CMK ID 进行加解密操作。
使用 KMS 加密方式前,需要开通 KMS 服务。具体操作,请参见开通密钥管理服务 。
加密算法
可选择 AES256 或 SM4 加密算法。 仅支持 AES256 加密算法。
加密密钥
仅当加密方式 选择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 处于相同地域的普通密钥或外部密钥。具体操作,请参见创建密钥 。
单击保存 。
使用阿里云 SDK
方式一:为 Bucket 开启服务器端加密
SDK 支持为已创建的 Bucket 开启服务器端加密,不支持在创建 Bucket 时开启服务器端加密。以下仅列举常见 SDK 为已创建的 Bucket 开启服务器端加密的代码示例。关于其他 SDK 为已创建的 Bucket 开启服务器端加密的代码示例,请参见SDK 简介 。
Java
PHP
Node.js
Python
C#
Go
C++
Java
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 {
String endpoint = "https://oss-cn-hangzhou.aliyuncs.com" ;
EnvironmentVariableCredentialsProvider credentialsProvider = CredentialsProviderFactory.newEnvironmentVariableCredentialsProvider();
String bucketName = "examplebucket" ;
String region = "cn-hangzhou" ;
ClientBuilderConfiguration clientBuilderConfiguration = new ClientBuilderConfiguration ();
clientBuilderConfiguration.setSignatureVersion(SignVersion.V4);
OSS ossClient = OSSClientBuilder.create()
.endpoint(endpoint)
.credentialsProvider(credentialsProvider)
.clientConfiguration(clientBuilderConfiguration)
.region(region)
.build();
try {
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
<?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 ;
$provider = new EnvironmentVariableCredentialsProvider ();
$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 {
$config = new ServerSideEncryptionConfig ("AES256" );
$ossClient ->putBucketEncryption ($bucket , $config );
$config = new ServerSideEncryptionConfig ("KMS" );
$ossClient ->putBucketEncryption ($bucket , $config );
$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" );
Node.js
const OSS = require ("ali-oss" );
const client = new OSS ({
region : 'yourregion' ,
accessKeyId : process.env .OSS_ACCESS_KEY_ID ,
accessKeySecret : process.env .OSS_ACCESS_KEY_SECRET ,
authorizationV4 : true ,
bucket : 'yourbucketname'
});
async function putBucketEncryption ( ) {
try {
const result = await client.putBucketEncryption ("bucket-name" , {
SSEAlgorithm : "AES256" ,
});
console .log (result);
} catch (e) {
console .log (e);
}
}
putBucketEncryption ();
Python
import oss2
from oss2.credentials import EnvironmentVariableCredentialsProvider
from oss2.models import ServerSideEncryptionRule
auth = oss2.ProviderAuthV4(EnvironmentVariableCredentialsProvider())
endpoint = "https://oss-cn-hangzhou.aliyuncs.com"
region = "cn-hangzhou"
bucket = oss2.Bucket(auth, endpoint, "examplebucket" , region=region)
rule = ServerSideEncryptionRule()
rule.sse_algorithm = oss2.SERVER_SIDE_ENCRYPTION_AES256
rule.kms_master_keyid = ""
result = bucket.put_bucket_encryption(rule)
print ('http response code:' , result.status)
C#
using Aliyun.OSS;
using Aliyun.OSS.Common;
var endpoint = "yourEndpoint" ;
var accessKeyId = Environment.GetEnvironmentVariable("OSS_ACCESS_KEY_ID" );
var accessKeySecret = Environment.GetEnvironmentVariable("OSS_ACCESS_KEY_SECRET" );
var bucketName = "examplebucket" ;
const string region = "cn-hangzhou" ;
var conf = new ClientConfiguration();
conf.SignatureVersion = SignatureVersion.V4;
var client = new OssClient(endpoint, accessKeyId, accessKeySecret, conf);
c.SetRegion(region);
try
{
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);
}
Go
package main
import (
"log"
"github.com/aliyun/aliyun-oss-go-sdk/oss"
)
func main () {
provider, err := oss.NewEnvironmentVariableCredentialsProvider()
if err != nil {
log.Fatalf("Error creating credentials provider: %v" , err)
}
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)
}
config := oss.ServerEncryptionRule{
SSEDefault: oss.SSEDefaultRule{
SSEAlgorithm: "AES256" ,
},
}
err = client.SetBucketEncryption("yourBucketName" , config)
if err != nil {
log.Fatalf("Error setting bucket encryption: %v" , err)
}
log.Println("Bucket encryption set successfully" )
}
C++
#include <alibabacloud/oss/OssClient.h>
using namespace AlibabaCloud::OSS;
int main (void )
{
std::string Endpoint = "yourEndpoint" ;
std::string Region = "yourRegion" ;
std::string BucketName = "examplebucket" ;
InitializeSdk ();
ClientConfiguration conf;
conf.signatureVersion = SignatureVersionType::V4;
auto credentialsProvider = std::make_shared <EnvironmentVariableCredentialsProvider>();
OssClient client (Endpoint, credentialsProvider, conf) ;
client.SetRegion (Region);
SetBucketEncryptionRequest setrequest (BucketName) ;
setrequest.setSSEAlgorithm (SSEAlgorithm::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 简介 。
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 {
String endpoint = "https://oss-cn-hangzhou.aliyuncs.com" ;
EnvironmentVariableCredentialsProvider credentialsProvider = CredentialsProviderFactory.newEnvironmentVariableCredentialsProvider();
String bucketName = "examplebucket" ;
String objectName = "exampledir/exampleobject.txt" ;
String filePath= "D:\\localpath\\examplefile.txt" ;
OSS ossClient = new OSSClientBuilder ().build(endpoint, credentialsProvider);
try {
ObjectMetadata metadata = new ObjectMetadata ();
metadata.setHeader(OSSHeaders.OSS_SERVER_SIDE_ENCRYPTION, "AES256" );
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
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 ;
$provider = new EnvironmentVariableCredentialsProvider ();
$endpoint = "https://oss-cn-hangzhou.aliyuncs.com" ;
$bucket = "examplebucket" ;
$object = "exampledir/exampleobject.txt" ;
$filePath = "D:\\localpath\\examplefile.txt" ;
try {
$config = array (
"provider" => $provider ,
"endpoint" => $endpoint ,
);
$ossClient = new OssClient ($config );
$options [OssClient ::OSS_HEADERS ] = array (
"x-oss-server-side-encryption" =>"AES256" ,
);
$ossClient ->uploadFile ($bucket , $object , $filePath , $options );
} catch (OssException $e ) {
printf (__FUNCTION__ . ": FAILED\n" );
printf ($e ->getMessage () . "\n" );
return ;
}
print (__FUNCTION__ . "OK" . "\n" );
const OSS = require ("ali-oss" );
const path = require ("path" );
const client = new OSS ({
region : "oss-cn-hangzhou" ,
accessKeyId : process.env .OSS_ACCESS_KEY_ID ,
accessKeySecret : process.env .OSS_ACCESS_KEY_SECRET ,
bucket : "examplebucket" ,
});
const headers = {
"x-oss-server-side-encryption" : "AES256" ,
};
async function put ( ) {
try {。
const result = await client.put (
"exampledir/exampleobject.txt" ,
path.normalize ("D:\\examplefile.jpg" ),
{ headers }
);
console .log (result);
} catch (e) {
console .log (e);
}
}
put ();
import oss2
import os
from oss2.credentials import EnvironmentVariableCredentialsProvider
auth = oss2.ProviderAuth(EnvironmentVariableCredentialsProvider())
endpoint = 'https://oss-cn-hangzhou.aliyuncs.com'
bucket_name = 'examplebucket0703'
bucket = oss2.Bucket(auth, endpoint, bucket_name)
local_file_path = 'D:\\examplefile.jpg'
with open (local_file_path, 'rb' ) as fileobj:
fileobj.seek(1000 , os.SEEK_SET)
current = fileobj.tell()
headers = {
'x-oss-server-side-encryption' : 'AES256' ,
}
object_key = 'exampledir/object1.jpg'
bucket.put_object(object_key, fileobj, headers=headers)
package main
import (
"fmt"
"github.com/aliyun/aliyun-oss-go-sdk/oss"
"os"
)
func main () {
provider, err := oss.NewEnvironmentVariableCredentialsProvider()
if err != nil {
fmt.Println("Error:" , err)
os.Exit(-1 )
}
client, err := oss.New("https://oss-cn-hangzhou.aliyuncs.com" , "" , "" , oss.SetCredentialsProvider(&provider))
if err != nil {
fmt.Println("Error:" , err)
os.Exit(-1 )
}
bucket, err := client.Bucket("examplebucket" )
if err != nil {
fmt.Println("Error:" , err)
os.Exit(-1 )
}
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 加密方式的逻辑示意图如下。
使用 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 时才会自动解密。
配置方式如下:
配置 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 算法。
配置方式如下:
权限说明 RAM 用户在不同场景中使用服务端加解密的权限说明如下:
设置 Bucket 加密方式
上传文件至设置了加密方式的 Bucket
从设置了加密方式的 Bucket 中下载文件
常见问题 配置 Bucket 加密方式后,OSS 会对历史文件进行加密吗?
OSS 只对服务器端加密配置生效后上传的 Object 进行加密,不会加密历史文件。如果您需要加密历史文件,可通过 CopyObject 覆写历史文件。