服务器端加密存储使用文档

简述

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的加密算法,目前仅支持AES256x-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-encryptionSSE-NOS的加密算法x-nos-server-side-encryption:AES256

相关 API

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的加密算法,目前仅支持AES256x-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-algorithmx-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-algorithmSSE-C的加密算法x-nos-server-side-encryption:AES256
x-nos-server-side-encryption-customer-key-MD5SSE-C的密钥的MD5x-nos-server-side-encryption-customer-key-MD5:71bf81259e7277040db9d916d6ef07d1

相关 API

使用样例 (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);