服务器端加密存储使用文档
简述
NOS提供了服务端加密(Server-Side Encryption,简称SSE)功能,用于对NOS上的持久化数据进行加密保护。NOS服务端加密支持以下两种方式,用户可以根据需要进行选择:
- NOS完全托管的服务端加密(Server-Side Encryption with NOS-Managed Encryption Keys,简称SSE-NOS)
数据加密密钥的生成和管理由NOS负责。用户在上传数据时,提供加密算法,NOS使用生成的密钥加密数据并进行保存。用户在下载数据时,NOS使用保存的密钥对数据进行解密,将解密后的原始数据返回给用户。 - 用户管理秘钥的服务端加密(Server-Side Encryption with Customer-Provided Encryption Keys,简称SSE-C)
数据加密密钥的管理完全由用户负责,NOS不保存密钥。用户在上传数据时,提供加密算法和加密密钥,NOS将数据加密后进行保存,NOS不保存加密密钥,只保存密钥的MD5用于后续的密钥校验。用户在下载数据时,需要提供加密算法和加密密钥,NOS通过MD5检查密钥的合法性,如果密钥合法,NOS将使用用户提供的密钥对数据解密返回给用户。
Attention
对于使用服务端加密或客户端加密的对象,GET Object必须使用https,若使用http,则报400 Bad Request错误。
NOS完全托管的服务端加密(SSE-NOS)
操作请求
在使用NOS完全托管的服务端加密(SSE-NOS) 时,用户需要使用以下请求标头提供加密密钥信息:
名称 | 描述 | 示例 |
---|---|---|
x-nos-server-side-encryption | 指定SSE-NOS的加密算法,目前仅支持AES256 | x-nos-server-side-encryption:AES256 |
以下 API 支持这些标头:
- Put Object: 简单上传
- Copy Object: 复制Object
- Initiate Multipart Upload: 分片上传
说明
- 如果用户指定
x-nos-server-side-encryption
头不为有效值,NOS 会直接返回 HTTP 状态码:400;并在消息体内注明错误码是:InvalidEncryptAlgorithm
- Copy Object请求中
x-nos-server-side-encryption
仅对目标对象有效,不影响源对象的存储
操作响应
使用NOS完全托管的服务端加密进行存储的Object,以下API请求中会返回 x-nos-server-side-encryption
标头:
- Put Object
- Copy Object
- Initiate Multipart Upload
- Upload Part
- Complete Multipart Upload
- Get Object
- Head Object
Meta信息
使用NOS完全托管的服务端加密进行存储的Object,其 Meta
信息会增加以下字段:
名称 | 描述 | 示例 |
---|---|---|
x-nos-server-side-encryption | SSE-NOS的加密算法 | x-nos-server-side-encryption:AES256 |
相关 API
- API: Put Object
- API: Copy Object
- API: Initiate Multipart Upload
2.5 使用样例(Java SDK)
在PutObject时通过调用addSpecialHeader方法增加SSE-NOS请求标头实现NOS完全托管的服务端加密,具体样例如下:
try {
/* 要上传的文件路径 */
File file = new File("your-local-file-path");
/* 初始化NosClient */
NosClient nosClient = new NosClient(new BasicCredentials("your-access-key", "your-secret-key"));
nosClient.setEndpoint("nos-eastchina1.126.net");
/* 构造putObject请求,并添加服务端加密头部 */
PutObjectRequest request = new PutObjectRequest("your-bucket-name", "your-object-name", file);
//新版本SDK接口
request.setSSEAlgorithm("AES256");
/**老版本SDK请使用addSpecialHeader
request.addSpecialHeader("x-nos-server-side-encryption", "AES256");
**/
/* 执行putobject请求 */
nosClient.putObject(request);
} catch (Exception e) {
System.out.println(e.getMessage());
}
用户管理密钥的服务端加密(SSE-C)
操作请求
在使用用户管理密钥的服务端加密 (SSE-C) 时,用户需要使用以下请求标头提供加密密钥信息:
名称 | 描述 | 示例 |
---|---|---|
x-nos-server-side-encryption-customer-algorithm | 指定SSE-C的加密算法,目前仅支持AES256 | x-nos-server-side-encryption:AES256 |
x-nos-server-side-encryption-customer-key | 指定SSE-C的密钥 | x-nos-server-side-encryption-customer-key:gNx2UcuoL0M8ROv/rnRlgcyDsxIy8q7KPrvIuTE7h8A= |
x-nos-server-side-encryption-customer-key-MD5 | 指定SSE-C的密钥的MD5(用于防止密钥传输错误以及密钥校验) | x-nos-server-side-encryption-customer-key-MD5:U9x8kIEZtHzfRW3J+lFHmg== |
以下 API 支持这些标头:
- Put Object: 简单上传
- Copy Object: 复制Object
- Initiate Multipart Upload: 分片上传
说明
- 如果用户指定
x-nos-server-side-encryption-customer-algorithm
头不为有效值,NOS 会直接返回 HTTP 状态码:400;并在消息体内注明错误码是:InvalidEncryptAlgorithm
- Copy Object请求中,如果源对象是使用SSE-C加密的,则用户需要使用以下标头提供加密信息,以便NOS解密源对象并进行复制:
名称 | 说明 |
---|---|
x-nos-copy-source-server-side-encryption-customer-algorithm | 源对象的加密算法 |
x-nos-copy-source-server-side-encryption-customer-key | 源对象的加密密钥 |
x-nos-copy-source-server-side-encryption-customer-key-MD5 | 源对象的加密密钥的MD5 |
操作响应
使用NOS完全托管的服务端加密进行存储的Object,以下API请求中会返回 x-nos-server-side-encryption-customer-algorithm
和 x-nos-server-side-encryption-customer-key-MD5
标头:
- Put Object
- Copy Object
- Initiate Multipart Upload
- Upload Part
- Complete Multipart Upload
- Get Object
- Head Object
Meta信息
使用NOS完全托管的服务端加密进行存储的Object,其 Meta
信息会增加以下字段:
名称 | 描述 | 示例 |
---|---|---|
x-nos-server-side-encryption-customer-algorithm | SSE-C的加密算法 | x-nos-server-side-encryption:AES256 |
x-nos-server-side-encryption-customer-key-MD5 | SSE-C的密钥的MD5 | x-nos-server-side-encryption-customer-key-MD5:71bf81259e7277040db9d916d6ef07d1 |
相关 API
- API: Put Object
- API: Copy Object
- API: Initiate Multipart Upload
使用样例 (Java SDK)
在PutObject时通过调用addSpecialHeader方法增加SSE-C请求标头实现用户管理密钥的服务端加密,具体样例如下:
try {
/* 要上传的文件路径 */
File file = new File("your-local-file-path");
/* 初始化NosClient */
NosClient nosClient = new NosClient(new BasicCredentials("your-access-key", "your-secret-key"));
nosClient.setEndpoint("nos-eastchina1.126.net");
/* 构造putObject请求,并添加服务端加密头部 */
PutObjectRequest request = new PutObjectRequest("your-bucket-name", "your-object-name", file);
/* 生成 AES256 加密密钥 */
KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");
keyGenerator.init(256, new SecureRandom());
SecretKey secretKey = keyGenerator.generateKey();
/* 数据加密密钥, NOS不会保存该秘钥,请妥善保管 */
String key = Base64.encodeBase64String(secretKey.getEncoded());
//新版本SDK接口
request.setSSECKey("AES256",key);
/**老版本SDK请使用addSpecialHeader
request.addSpecialHeader("x-nos-server-side-encryption-customer-algorithm", "AES256");
// 计算数据加密密钥的MD5码,用于校验
String keyMd5 = Base64.encodeBase64String(DigestUtils.md5(Base64.decodeBase64(key)));
//添加SSE-C加密头部
request.addSpecialHeader("x-nos-server-side-encryption-customer-key", key);
request.addSpecialHeader("x-nos-server-side-encryption-customer-key-MD5", keyMd5);
**/
/* 执行putobject请求 */
nosClient.putObject(request);
} catch (Exception e) {
System.out.println(e.getMessage());
}
与 Amazon S3 兼容
NOS 兼容 Amazon S3 的 SSE-S3 与 SSE-C 功能,用户可以参照 Amazon S3 文档 通过 Amazon S3 提供的 REST API 和 SDK 调用 NOS 的 SSE-NOS 和 SSE-C 功能。
通过 Amazon S3 SDK 使用 NOS SSE-NOS 上传文件
//初始化 Amazon S3 客户端
AWSCredentials credentials = new BasicAWSCredentials("your-access-key","your-secret-key");
AWSCredentialsProvider credentialsProvider = new AWSStaticCredentialsProvide(credentials);
AmazonS3 s3Client = AmazonS3ClientBuilder.standard()
.withCredentials(credentialsProvider)
.withEndpointConfiguration(new AwsClientBuilder.EndpointConfiguration("nos-eastchina1.126.net", "eastchina1"))
.build();
PutObjectRequest putObjectRequest = new PutObjectRequest("your-bucket-name","your-object-name", new File("your-local-file-path"));
//通过 ObjectMetadata 指定 SSE 算法
ObjectMetadata objectMetadata = new ObjectMetadata();
objectMetadata.setSSEAlgorithm("AES256");
putObjectRequest.setMetadata(objectMetadata);
//上传文件
s3Client.putObject(putObjectRequest);
通过 Amazon S3 SDK 使用 NOS SSE-C 上传文件
//初始化 Amazon S3 客户端
AWSCredentials credentials = new BasicAWSCredentials("your-access-key","your-secret-key");
AWSCredentialsProvider credentialsProvider = new AWSStaticCredentialsProvide(credentials);
AmazonS3 s3Client = AmazonS3ClientBuilder.standard()
.withCredentials(credentialsProvider)
.withEndpointConfiguration(new AwsClientBuilder.EndpointConfiguration("nos-eastchina1.126.net", "eastchina1"))
.build();
//生成加密密钥
KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");
keyGenerator.init(256, new SecureRandom());
SSECustomerKey ssecKey = new SSECustomerKey(keyGenerator.generateKey());
PutObjectRequest putObjectRequest = new PutObjectRequest("your-bucket-name","your-object-name", new File("your-local-file-path"));
//设置加密密钥
putObjectRequest.setSSECustomerKey(ssecKey);
//上传文件
s3Client.putObject(putObjectRequest);