全部产品
Search
文档中心

对象存储 OSS:Java服务器端加密

更新时间:Dec 20, 2023

OSS支持在服务器端对上传的数据进行加密编码(Server-Side Encryption)。上传数据时,OSS对收到的用户数据进行加密,然后再将得到的加密数据持久化保存下来。下载数据时,OSS自动对保存的加密数据进行解密并把原始数据返回给用户,并在返回的HTTP请求Header中,声明该数据进行了服务器端加密。

注意事项

  • 本文以华东1(杭州)外网Endpoint为例。如果您希望通过与OSS同地域的其他阿里云产品访问OSS,请使用内网Endpoint。关于OSS支持的Region与Endpoint的对应关系,请参见访问域名和数据中心

  • 本文以从环境变量读取访问凭证为例。如何配置访问凭证,请参见Java配置访问凭证

  • 本文以OSS域名新建OSSClient为例。如果您希望通过自定义域名、STS等方式新建OSSClient,请参见新建OSSClient

  • 要配置Bucket加密,您必须具有oss:PutBucketEncryption权限;要获取Bucket加密配置,您必须具有oss:GetBucketEncryption权限;要删除Bucket加密配置,您必须具有oss:DeleteBucketEncryption权限。具体操作,请参见为RAM用户授权自定义的权限策略

背景信息

OSS有如下两种服务器端加密方式:

  • 使用OSS托管的CMK进行加密(SSE-KMS)

    上传文件时,可以使用指定的CMK ID或者OSS托管的CMK进行加密操作。数据无需通过网络发送到KMS服务端进行加解密,是一种低成本的加解密方式。

    重要

    使用KMS密钥功能时会产生少量的KMS密钥API调用费用,费用详情请参见KMS计费标准

  • 使用OSS完全托管加密(SSE-OSS)

    上传文件时,OSS服务端使用完全托管的AES256进行加密操作。OSS会为每个对象使用不同的密钥进行加密,作为额外的保护,它将使用定期轮转的主密钥对加密密钥本身进行加密。

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

  • 如果配置了Bucket加密,仍然可以在上传或拷贝Object时单独对Object配置加密方式,且以Object配置的加密方式为准。详情请参见PutObject

  • 更多关于服务器端加密的介绍,请参见服务器端加密

配置Bucket加密

您可以通过以下代码设置Bucket默认加密方式,设置成功之后,所有上传至该Bucket但未设置加密方式的Object都会使用Bucket默认加密方式进行加密:

  • 使用OSS托管的CMK进行加密(SSE-KMS)

    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";
            // 填写KMS用户主密钥ID。您可以通过阿里云KMS管理控制台创建用户主密钥,并获取用户主密钥ID。
            String kmsId = "e1935511-cf88-1123-a0f8-1be8d2511***";
    
            // 创建OSSClient实例。
            OSS ossClient = new OSSClientBuilder().build(endpoint, credentialsProvider);
    
            try {
                // 设置Bucket加密。
                ServerSideEncryptionByDefault applyServerSideEncryptionByDefault = new ServerSideEncryptionByDefault(SSEAlgorithm.KMS);
                applyServerSideEncryptionByDefault.setKMSMasterKeyID(kmsId);
                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();
                }
            }
        }
    }      
  • 使用OSS完全托管加密(SSE-OSS)

    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";
    
            // 创建OSSClient实例。
            OSS ossClient = new OSSClientBuilder().build(endpoint, credentialsProvider);
    
            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();
                }
            }
        }
    }

获取Bucket加密配置

以下代码用于获取Bucket加密配置:

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";

        // 创建OSSClient实例。
        OSS ossClient = new OSSClientBuilder().build(endpoint, credentialsProvider);

        try {
            // 获取Bucket加密配置。
            ServerSideEncryptionConfiguration sseConfig = ossClient.getBucketEncryption(bucketName);
            System.out.println("get Algorithm: " + sseConfig.getApplyServerSideEncryptionByDefault().getSSEAlgorithm());
            System.out.println("get kmsid: " + sseConfig.getApplyServerSideEncryptionByDefault().getKMSMasterKeyID());
        } 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();
            }
        }
    }
}

删除Bucket加密配置

以下代码用于删除Bucket加密配置:

import com.aliyun.oss.*;
import com.aliyun.oss.common.auth.*;

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";

        // 创建OSSClient实例。
        OSS ossClient = new OSSClientBuilder().build(endpoint, credentialsProvider);

        try {
            // 删除Bucket加密配置。
            ossClient.deleteBucketEncryption(bucketName);
        } 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();
            }
        }
    }
}

相关文档