服务端加密

最后更新时间:2021-06-11 16:50:42

    简介

    本文档提供关于服务端加密操作相关的 API 概览以及 SDK 示例代码。

    API 操作名 操作描述
    PUT Bucket encryption 设置存储桶加密 设置指定存储桶下的默认加密配置
    GET Bucket encryption 查询存储桶加密 查询指定存储桶下的默认加密配置
    DELETE Bucket encryption 删除存储桶加密 删除指定存储桶下的默认加密配置

    使用 COS 托管加密密钥的服务端加密(SSE-COS)保护数据

    功能说明

    由腾讯云 COS 托管主密钥和管理数据。COS 会帮助您在数据写入数据中心时自动加密,并在您取用该数据时自动解密。目前支持使用 COS 主密钥对数据进行 AES-256 加密。

    示例代码

    SDK 通过调用 setServerSideEncryptionsetMetadata等方法来完成,示例如下:

    java
    // 初始化用户身份信息(secretId, secretKey)
    // SECRETID和SECRETKEY请登录访问管理控制台进行查看和管理
    String secretId = "SECRETID";
    String secretKey = "SECRETKEY";
    COSCredentials cred = new BasicCOSCredentials(secretId, secretKey);
    // 设置bucket的地域, COS地域的简称请参照 https://intl.cloud.tencent.com/document/product/436/6224?from_cn_redirect=1
    ClientConfig clientConfig = new ClientConfig(new Region("ap-guangzhou"));
    // 生成cos客户端
    COSClient cosclient = new COSClient(cred, clientConfig);
    // bucket名需包含appid
    String bucketName = "examplebucket-1250000000";
    String key = "doc/exampleobject.txt";
    File localFile = new File("test.txt");
    PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, key, localFile);
    ObjectMetadata objectMetadata = new ObjectMetadata();
    // 设置加密算法为AES256
    objectMetadata.setServerSideEncryption(SSEAlgorithm.AES256.getAlgorithm());
    putObjectRequest.setMetadata(objectMetadata);
    try {
     PutObjectResult putObjectResult = cosclient.putObject(putObjectRequest);
     // putobjectResult会返回文件的 etag, 该 md5值根据s3语义不是对象的md5,只是唯一性标志
     String etag = putObjectResult.getETag();
    } catch (CosServiceException e) {
     e.printStackTrace();
    } catch (CosClientException e) {
     e.printStackTrace();
    }
    // 关闭客户端
    cosclient.shutdown();
    

    使用 KMS 托管加密密钥的服务端加密(SSE-KMS)保护数据

    功能说明

    由腾讯云密钥管理系统 KMS 托管密钥的服务端加密方式,可选择使用默认密钥或自建密钥。关于密钥信息,可参见 创建 KMS 密钥,关于 SSE-KMS 的更多信息,请参见 服务端加密概述:SSE-KMS

    示例代码

    示例1:简单上传的对象使用 KMS 加密

    java
    COSCredentials cred = new BasicCOSCredentials("SECRET_ID", "SECRET_KEY");
    // 2 设置bucket的地域, COS地域的简称请参照 https://intl.cloud.tencent.com/document/product/436/6224?from_cn_redirect=1
    ClientConfig clientConfig = new ClientConfig(new Region("ap-guangzhou"));
    // 设置使用https请求
    clientConfig.setHttpProtocol(HttpProtocol.https);
    // 3 生成cos客户端
    COSClient cosclient = new COSClient(cred, clientConfig);
    // bucket名需包含appid
    String bucketName = "examplebucket-1250000000";
    String key = "doc/exampleobject.txt";
    File localFile = new File("/test.log");
    PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, key, localFile);
    String kmsKeyId = "your-kms-key-id";
    String encryptionContext = Base64.encodeAsString("{\"Ssekmstest\":\"Ssekmstest\"}".getBytes());
    SSECOSKeyManagementParams ssecosKeyManagementParams = new SSECOSKeyManagementParams(kmsKeyId, encryptionContext);
    putObjectRequest.setSSECOSKeyManagementParams(ssecosKeyManagementParams);
    // 服务端加密场景下,返回的etag不再代表文件的md5,所以需要去掉客户端的md5校验
    // 如有需要,可获取crc64,自行校验
    System.setProperty(SkipMd5CheckStrategy.DISABLE_PUT_OBJECT_MD5_VALIDATION_PROPERTY, "true");
    try {
      PutObjectResult putObjectResult = cosclient.putObject(putObjectRequest);
      // putobjectResult会返回文件的etag
      String etag = putObjectResult.getETag();
      String crc64 = putObjectResult.getCrc64Ecma();
    } catch (CosServiceException e) {
      e.printStackTrace();
    } catch (CosClientException e) {
      e.printStackTrace();
    }
    // 关闭客户端
    cosclient.shutdown();
    

    示例2:分块上传的对象使用 KMS 加密

    java
    COSCredentials cred = new BasicCOSCredentials("SECRET_ID", "SECRET_KEY");
    // 2 设置bucket的地域, COS地域的简称请参照 https://intl.cloud.tencent.com/document/product/436/6224?from_cn_redirect=1
    ClientConfig clientConfig = new ClientConfig(new Region("ap-guangzhou"));
    // 设置使用https请求
    clientConfig.setHttpProtocol(HttpProtocol.https);
    // 3 生成cos客户端
    COSClient cosclient = new COSClient(cred, clientConfig);
    // bucket名需包含appid
    String bucketName = "examplebucket-1250000000";
    String key = "doc/exampleobject.txt";
    String kmsKeyId = "your-kms-key-id";
    String encryptionContext = Base64.encodeAsString("{\"Ssekmstest\":\"Ssekmstest\"}".getBytes());
    InitiateMultipartUploadRequest initiateMultipartUploadRequest = new InitiateMultipartUploadRequest(bucketName, key);
    SSECOSKeyManagementParams ssecosKeyManagementParams = new SSECOSKeyManagementParams(kmsKeyId, encryptionContext);
    // 服务端加密场景下,返回的etag不再代表文件的md5,所以需要去掉客户端的md5校验
    // 如有需要,可获取crc64,自行校验
    System.setProperty(SkipMd5CheckStrategy.DISABLE_PUT_OBJECT_MD5_VALIDATION_PROPERTY, "true");
    initiateMultipartUploadRequest.setSSECOSKeyManagementParams(ssecosKeyManagementParams);
    try {
      InitiateMultipartUploadResult initiateMultipartUploadResult = cosclient.initiateMultipartUpload(initiateMultipartUploadRequest);
      List<PartETag> partETags = new LinkedList<>();
      for (int i = 0; i < 2; i++) {
          byte data[] = new byte[1024 * 1024];
          UploadPartRequest uploadPartRequest = new UploadPartRequest();
          uploadPartRequest.setBucketName(bucketName);
          uploadPartRequest.setKey(key);
          uploadPartRequest.setUploadId(initiateMultipartUploadResult.getUploadId());
          // 设置分块的数据来源输入流
          uploadPartRequest.setInputStream(new ByteArrayInputStream(data));
          // 设置分块的长度
          uploadPartRequest.setPartSize(data.length); // 设置数据长度
          uploadPartRequest.setPartNumber(i + 1);     // 假设要上传的part编号是10
           UploadPartResult uploadPartResult = cosclient.uploadPart(uploadPartRequest);
          PartETag partETag = uploadPartResult.getPartETag();
          partETags.add(partETag);
      }
      CompleteMultipartUploadRequest completeMultipartUploadRequest =
      new CompleteMultipartUploadRequest(bucketName, key, initiateMultipartUploadResult.getUploadId(), partETags);
      CompleteMultipartUploadResult completeResult =
      cosclient.completeMultipartUpload(completeMultipartUploadRequest);
    } catch (CosServiceException e) {
      e.printStackTrace();
    } catch (CosClientException e) {
      e.printStackTrace();
    }
    // 关闭客户端
    cosclient.shutdown();
    

    示例3:拷贝生成的目标对象使用 KMS 加密

    java
    COSCredentials cred = new BasicCOSCredentials("SECRET_ID", "SECRET_KEY");
    // 2 设置bucket的地域, COS地域的简称请参照 https://intl.cloud.tencent.com/document/product/436/6224?from_cn_redirect=1
    ClientConfig clientConfig = new ClientConfig(new Region("ap-guangzhou"));
    // 设置使用https请求
    clientConfig.setHttpProtocol(HttpProtocol.https);
    // 3 生成cos客户端
    COSClient cosclient = new COSClient(cred, clientConfig);
    // bucket名需包含appid
    String kmsKeyId = "your-kms-key-id";
    String encryptionContext = Base64.encodeAsString("{\"Ssekmstest\":\"Ssekmstest\"}".getBytes());
    // 要拷贝的bucket region, 支持跨地域拷贝
    Region srcBucketRegion = new Region("ap-guangzhou");
    // 源bucket, bucket名需包含appid
    String srcBucketName = "examplebucket-1250000000";
    // 要拷贝的源文件
    String srcKey = "doc/exampleobject.txt";
    // 目的bucket, bucket名需包含appid
    String destBucketName = "examplebucket-1250000000";
    // 要拷贝的目的文件
    String destKey = "folder/exampleobject.txt";
    CopyObjectRequest copyObjectRequest = new CopyObjectRequest(srcBucketRegion, srcBucketName,
                                                              srcKey, destBucketName, destKey);
    copyObjectRequest.setSSECOSKeyManagementParams(new SSECOSKeyManagementParams(kmsKeyId, encryptionContext));
    try {
      CopyObjectResult copyObjectResult = cosclient.copyObject(copyObjectRequest);
      String crc64 = copyObjectResult.getCrc64Ecma();
    } catch (CosServiceException e) {
      e.printStackTrace();
    } catch (CosClientException e) {
      e.printStackTrace();
    }
    // 关闭客户端
    cosclient.shutdown();
    

    使用客户提供的加密密钥的服务端加密 (SSE-C)保护数据

    功能说明

    加密密钥由用户自己提供,用户在上传对象时,COS 将使用用户提供的加密密钥对用户的数据进行 AES-256 加密。SDK 通过调用setHttpProtocolsetSSECustomerKey 等方法来完成。

    注意:

    • 该加密所运行的服务需要使用 HTTPS 请求。
    • base64EncodedKey:用户提供的服务端加密密钥的 Base64 编码。
    • 如果上传的源文件调用了该方法,那么在使用 GET(下载)、HEAD(查询)时对源对象操作的时候也要调用该方法。

    示例代码

    java
    // 初始化用户身份信息(secretId, secretKey)
    // SECRETID和SECRETKEY请登录访问管理控制台进行查看和管理
    String secretId = "SECRETID";
    String secretKey = "SECRETKEY";
    COSCredentials cred = new BasicCOSCredentials(secretId, secretKey);
    // 设置bucket的地域, COS地域的简称请参照 https://www.qcloud.com/document/product/436/6224
    ClientConfig clientConfig = new ClientConfig(new Region("ap-guangzhou"));
    // 要求https协议
    clientConfig.setHttpProtocol(HttpProtocol.https);
    // 生成cos客户端
    COSClient cosclient = new COSClient(cred, clientConfig);
    // bucket名需包含appid
    String bucketName = "examplebucket-1250000000";
    String key = "doc/exampleobject.txt";
    File localFile = new File("test.txt");
    PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, key, localFile);
    String base64EncodedKey = "MDEyMzQ1Njc4OUFCQ0RFRjAxMjM0NTY3ODlBQkNERUY=";
    // sseCustomerKey是base64编码的密钥
    SSECustomerKey sseCustomerKey = new SSECustomerKey(base64EncodedKey);
    putObjectRequest.setSSECustomerKey(sseCustomerKey);
    ObjectMetadata objectMetadata = cosclient.getObjectMetadata();
    objectMetadata.getHttpExpiresDate();
    try {
    PutObjectResult putObjectResult = cosclient.putObject(putObjectRequest);
    // putobjectResult会返回文件的etag, 该md5值根据s3语义不是对象的md5,只是唯一性标志
    String etag = putObjectResult.getETag();
    } catch (CosServiceException e) {
    e.printStackTrace();
    } catch (CosClientException e) {
    e.printStackTrace();
    }
    // 关闭客户端
    cosclient.shutdown();