# SSE-KMS加密（KMS托管密钥）
SSE-KMS加密方式适用于对合规性、安全性要求较高的场景。SSE-KMS将密钥管理服务KMS和对象存储服务OBS结合起来，KMS为OBS提供密钥，OBS使用密钥加密上传到桶中的数据。该密钥由经过安全认证的第三方硬件安全模块（HSM）产生，对密钥的关键操作都会进行访问控制及日志跟踪，安全性更高。您还可以借助KMS来管理密钥，例如使用KMS创建自定义密钥，编辑、查询和删除密钥。
#### 背景介绍
使用SSE-KMS加密方式时，您可能想要了解以下背景知识：
- 密码安全中心（Key Management Service，以下简称KMS），是华为云提供的一种安全、可靠、简单易用的密钥托管服务，您可以使用DEW创建并管理您的密钥，DEW生成的密钥可应用于OBS服务端加密，了解更多请参见[KMS服务简介](https://support.huaweicloud.com/productdesc-dew/dew_01_0001.html)。
- **用户主密钥** （Customer Master Key，以下简称CMK）是DEW加密系统中最高级别的密钥，用于生成和管理其他密钥（如会话密钥、数据加密密钥等）。主密钥有**自定义密钥** 和**默认密钥** 两种，配置OBS的SSE-KMS加密方式时，您可以根据业务需要任选一种参与SSE-KMS加密，如未指定则首次使用SSE-KMS加密数据时，系统会自动为当前华为云账号创建一个"默认密钥"并默认使用。了解更多请参见[KMS基本概念说明](https://support.huaweicloud.com/productdesc-dew/dew_01_0321.html)、[默认密钥如何生成](https://support.huaweicloud.com/dew_faq/dew_01_0168.html)、[自定义密钥与默认密钥有什么区别](https://support.huaweicloud.com/dew_faq/dew_01_0044.html)、[创建自定义密钥](https://support.huaweicloud.com/usermanual-dew/dew_01_0178.html)。
- **数据加密密钥**（Data Encrypt Key，以下简称DEK）：用于直接加密数据的密钥。
- **信封加密** （Envelope Encryption）是一种加密手段，不使用用户主密钥直接加解密数据，而是通过主密钥派生数据加密密钥，使用"数据加密密钥"加解密数据明文，然后使用"主密钥"加解密"数据加密密钥"。了解更多参见[信封加密方式有什么优势](https://support.huaweicloud.com/dew_faq/dew_01_0054.html)。
 
#### 费用说明
如果您使用SSE-KMS加密方式，会涉及密钥管理服务KMS的计费，了解更多请参考[KMS计费项](https://support.huaweicloud.com/price-dew/dew_03_0006.html)。
#### 注意事项
- 由于密码安全中心服务接口存在流控限制（详见[DEW API概览](https://support.huaweicloud.com/api-dew/dew_02_0057.html)），开启SSE-KMS加密后，您的业务访问可能会受流控影响。
- 加密后对象的ETag值不是对象明文的MD5值，而是对象密文的MD5值。
 
#### 约束限制
- SSE-KMS支持**AES256** 、**SM4**两种加密算法。
- 设置桶的加密方式为SSE-KMS，以及其他使用SSE-KMS加解密的所有GET、PUT类请求必须使用HTTPS协议。
- 匿名用户不能访问被SSE-KMS加密的对象，必须使用有效的凭证（访问密钥或临时访问密钥）对请求进行签名，更多签名相关信息参见[OBS签名](https://support.huaweicloud.com/api-obs/obs_04_0009.html)。
- 如果您使用CMK自定义密钥，那么开启服务端加密的桶，必须和自定义密钥处于同一区域中。默认密钥不区分区域和IAM用户，单个华为云账号内所有IAM用户、所有区域共有一个默认密钥。
- 仅支持使用**AES256** 、**SM4** 的**CMK自定义密钥**，请在创建CMK自定义密钥时选择正确的加密算法。
- 跨账号访问场景请使用**自定义密钥**进行SSE-KMS加密。
 
#### SSE-KMS原理介绍
图1SSE-KMS加密流程   
![](https://support.huaweicloud.com/usermanual-obs/figure/zh-cn_image_0000002394167737.png "点击放大")
加密对象时，如[图1]所示，SSE-KMS采用[信封加密]机制，加密流程如下：
1. DEW通过[CMK]派生出[DEK]，然后使用CMK加密DEK得到DEK的密文，DEW将DEK的明文和密文一同发送给OBS。
2. OBS使用DEK明文加密数据，并在使用后将DEK明文尽快从内存中删除。
3. OBS将DEK密文作为元数据与对象密文一起存储。
图2SSE-KMS解密流程   
![](https://support.huaweicloud.com/usermanual-obs/figure/zh-cn_image_0000002554563503.png "点击放大")
解密对象时，如[图2]所示，解密流程如下：
1. OBS向DEW发送DEK密文，申请DEW解密DEK。
2. DEW使用与加密过程相同的CMK为DEK解密，然后将DEK明文返回OBS。
3. OBS使用DEK明文解密对象密文，得到对象明文，并尽快从内存中删除DEK明文。
 
 #### 相关权限配置
**配置桶加密方式、上传下载加密对象需要配置相关权限：**
- 设置桶的加密方式为SSE-KMS，您必须是桶拥有者或拥有设置桶加密方式的权限。建议使用IAM或桶策略进行授权，如果使用IAM则需授予**obs:bucket:** **PutEncryptionConfiguration** 、**obs:bucket:** **GetEncryptionConfiguration** 权限，如果使用桶策略则需授予**PutEncryptionConfiguration** 、**GetEncryptionConfiguration** 权限。相关授权方式介绍可参见[OBS权限控制概述](https://support.huaweicloud.com/perms-cfg-obs/obs_40_0001.html)，配置方式详见[使用IAM自定义策略](https://support.huaweicloud.com/usermanual-obs/obs_03_0121.html)和[自定义创建桶策略](https://support.huaweicloud.com/usermanual-obs/obs_03_0123.html)。
- 上传对象时使用SSE-KMS方式加密对象，除了拥有对象上传权限，还需要使用IAM为请求者配置**kms:cmk:get、kms:cmk:list、kms:cmk:create、kms:dek:create**权限。
- 下载使用SSE-KMS加密的对象，除了拥有对象下载权限，还需要使用IAM为请求者配置kms:cmk:get、kms:cmk:list、kms:cmk:create、kms:dek:create、**kms:dek:encrypt、kms:dek:decrypt**权限。
 
**对桶的访问请求执行服务端加密限制：**
- 您可以通过设置桶策略，对桶的访问请求执行服务端加密限制。例如，要求使用PUT上传方式向名为ExampleBucket的桶中上传对象时，对象必须选择SSE-KMS加密方式，可使用以下桶策略达成，该桶策略拒绝不包含头域x-obs-server-side-encryption:"kms"的上传操作：
  ```
  {
      "Statement": [
          {
              "Sid": "DenyUnEncryptedObjectUploads",
              "Effect": "Deny",
              "Principal": "*",
              "Action": "PutObject",
              "Resource": "ExampleBucket/*",
              "Condition": {
                  "StringNotEquals": {
                      "x-obs-server-side-encryption": "kms"
                  }
              }
          }
      ]
  }
  ```
  
- **跨账号场景** **下授权其他账号访问被服务端加密的对象**
  例如华为云账号A用自己的密钥k加密了桶A中的对象a，此时华为云账号B想要访问对象a，需要完成桶和对象资源、密钥资源两方面的授权：
  - **桶和对象资源授权** ：账号A向账号B授权访问桶，详细操作可以参考[为其他账号授权](https://support.huaweicloud.com/perms-cfg-obs/obs_40_0024.html)。
  
  - **密钥资源授权** ：账号A向账号B授权访问密钥k，详细操作请参考[为自定义密钥创建授权](https://support.huaweicloud.com/usermanual-dew/dew_01_0096.html)。
   
  注意，跨账号访问场景请使用**自定义密钥**进行SSE-KMS加密。
  
 
#### 服务端加密对其他操作的影响
**对上传下载对象的影响**
只要您满足[相关权限要求]，您访问加密和未加密对象的方式没有区别。例如，如果您使用预签名的 URL来共享您的对象，那么对于加密和解密的对象，该 URL 的工作方式是相同的。此外，在您列出存储桶中的对象时，列举API操作会返回所有对象的列表（无论对象是否加密）。
**对于跨桶复制对象的影响（包括跨区域和同区域）**
- 当源桶未开启服务端加密，目标桶开启加密时，复制到目标桶的对象副本将被加密，且加密方式与目标桶保持一致。此时源对象的ETag与副本对象的ETag不同，如果您有使用ETag的应用程序，则需要适配该差异。
- 当源桶和目标桶都开启了服务端加密，但是加密方式不一致时，复制到目标桶的对象副本加密方式与目标桶保持一致。此时源对象的ETag与副本对象的ETag也不相同，请注意适配。
- 当源桶开启服务端加密，目标桶未开启时，复制到目标桶的对象副本将被加密，且加密方式与源桶保持一致。
#### 前提条件
如果您的用户主密钥计划使用自定义密钥，请在配置SSE-KMS之前，提前完成密钥创建，如何创建请参考[创建自定义密钥](https://support.huaweicloud.com/usermanual-dew/dew_01_0178.html)。
#### 为桶配置SSE-KMS加密
OBS支持通过[管理控制台](https://console.huaweicloud.com/console/?locale=zh-cn#/obs/manager/buckets)、API、SDK方式配置桶SSE-KMS加密，不支持通过OBS Browser+、obsutil方式配置。
#### 使用OBS控制台
本节仅介绍针对已有桶，如何开启服务端加密并配置SSE-KMS加密。创建桶时如何开启加密，请参见[创建桶](https://support.huaweicloud.com/usermanual-obs/zh-cn_topic_0045829088.html#ZH-CN_TOPIC_0000001952642149)。
1. 在OBS[管理控制台](https://console.huaweicloud.com/console/?locale=zh-cn#/obs/manager/buckets)左侧导航栏选择"桶列表"。
2. 在桶列表中，单击待操作的桶，进入"对象"页面。
3. 在左侧导航栏，单击"概览"，进入"概览"页。
4. 在概览页的"基础配置"区域下，单击"服务端加密"卡片，系统弹出"服务端加密"对话框。
5. 单击按钮开启服务端加密
6. 加密模式选择"SSE-KMS"。
7. 【可选，仅部分区域支持，例如华北-乌兰察布一】选择"加密算法"，在"AES256"、"SM4"中任选一种作为对象加密的算法。
8. 选择"加密密钥类型"。 
   表1加密密钥类型 
   | 参数名称 | 说明                                                                                                                                                                                                        ||
   |:---|:---|---|
   | 加密密钥类型 | 默认密钥  | 上传的对象将使用当前区域的默认密钥进行加密，如果您没有默认密钥，系统将会在首次上传对象时自动为您创建。                                                                     |
   | 加密密钥类型 | 自定义密钥 | 通过单击"查看KMS密钥"进入密码安全中心页面创建自定义密钥，然后通过KMS密钥的下拉框选中您创建的KMS密钥。                                                                 |
   | 加密密钥类型 | 共享密钥 | 输入共享密钥ID，您上传的对象将使用其他用户共享的密钥进行加密。获取共享密钥ID，具体请参见[查看密钥](https://support.huaweicloud.com/usermanual-dew/dew_01_0179.html)。 |
      
   
   
9. 单击"确定"。
 
#### 使用API
[设置桶的加密配置](https://support.huaweicloud.com/api-obs/obs_04_0062.html)
了解更多详见[服务端加密相关接口概览](https://support.huaweicloud.com/usermanual-obs/obs_03_0094.html#ZH-CN_TOPIC_0000002384025230)。
#### 使用SDK
| [Java](https://support.huaweicloud.com/sdk-java-devg-obs/obs_21_1901.html) | [Python](https://support.huaweicloud.com/sdk-python-devg-obs/obs_22_1303.html) | [C](https://support.huaweicloud.com/sdk-c-devg-obs/obs_20_1500.html) | [Go](https://support.huaweicloud.com/sdk-go-devg-obs/obs_33_0441.html) | [BrowserJS](https://support.huaweicloud.com/sdk-browserjs-devg-obs/obs_24_1500.html) | [.NET](https://support.huaweicloud.com/sdk-dotnet-devg-obs/obs_25_1500.html) | [Android](https://support.huaweicloud.com/sdk-android-devg-obs/obs_26_1500.html) | [iOS](https://support.huaweicloud.com/sdk-ios-devg-obs/obs_27_1500.html) | [PHP](https://support.huaweicloud.com/sdk-php-devg-obs/obs_28_1500.html) | [Node.js](https://support.huaweicloud.com/sdk-nodejs-devg-obs/obs_29_1500.html) |
|---|---|---|---|---|---|---|---|---|---|
   
#### 为对象配置SSE-KMS加密
OBS支持通过[管理控制台](https://console.huaweicloud.com/console/?locale=zh-cn#/obs/manager/buckets)、API、SDK方式对上传对象SSE-KMS进行加密，不支持通过OBS Browser+、obsutil方式配置。
#### 使用OBS控制台
1. 在OBS[管理控制台](https://console.huaweicloud.com/console/?locale=zh-cn#/obs/manager/buckets)左侧导航栏选择"桶列表"。
2. 在桶列表中，单击待操作的桶，进入"对象"页面。
3. 单击"上传对象"，系统弹出"上传对象"对话框。
4. 添加待上传的文件。
5. 如果您的桶未开启服务端加密，请单击开关，开启服务端加密。
6. 选择"加密模式"。 
   表2加密模式说明 
   | 加密模式参数      | 说明                                                                                                                                                               |
   |:---|:---|
   | 继承桶的加密配置 | 对象将会继承桶的加密配置。如果桶加密方式是SSE-KMS，且对象加密选择的密钥与桶相同，则选择该项，然后执行[9]。 |
   | SSE-KMS   | 使用SSE-KMS方式加密，选择该项后您可以根据业务选择"加密算法"、"加密密钥类型"和具体的加密密钥。                                                                                                            |
   | SSE-OBS     | 使用SSE-OBS方式加密，此处不选择。了解更多参见[SSE-OBS加密](https://support.huaweicloud.com/usermanual-obs/obs_03_0092.html#ZH-CN_TOPIC_0000002417584481)。                            |
      
   
   
7. 【可选，仅部分区域支持，例如华北-乌兰察布一】选择"加密算法"，在"AES256"、"SM4"中任选一种作为对象加密的算法。
8. 选择"加密密钥类型"。 
   表3加密密钥类型 
   | 参数名称  | 说明                                                                                                                                                                                                          ||
   |:---|:---|---|
   | 加密密钥类型 | 默认密钥   | 上传的对象将使用当前区域的默认密钥进行加密，如果您没有默认密钥，系统将会在首次上传对象时自动为您创建。                                                                   |
   | 加密密钥类型 | 自定义密钥 | 通过单击"查看KMS密钥"进入密码安全中心页面创建自定义密钥，然后通过KMS密钥的下拉框选中您创建的KMS密钥。                                                                |
   | 加密密钥类型 | 共享密钥  | 输入共享密钥ID，您上传的对象将使用其他用户共享的密钥进行加密。获取共享密钥ID，具体请参见[查看密钥](https://support.huaweicloud.com/usermanual-dew/dew_01_0179.html)。 |
      
   
   
9. 单击"确定"。
   
   对象上传成功后，可在对象详情中查看对象的加密状态。
   
   
 
#### 使用API
详见[服务端加密相关接口概览](https://support.huaweicloud.com/usermanual-obs/obs_03_0094.html#ZH-CN_TOPIC_0000002384025230)。
#### 使用SDK
| [Java](https://support.huaweicloud.com/sdk-java-devg-obs/obs_21_1901.html) | [Python](https://support.huaweicloud.com/sdk-python-devg-obs/obs_22_1303.html) | [C](https://support.huaweicloud.com/sdk-c-devg-obs/obs_20_1500.html) | [Go](https://support.huaweicloud.com/sdk-go-devg-obs/obs_33_0603.html) | [BrowserJS](https://support.huaweicloud.com/sdk-browserjs-devg-obs/obs_24_1500.html) | [.NET](https://support.huaweicloud.com/sdk-dotnet-devg-obs/obs_25_1500.html) | [Android](https://support.huaweicloud.com/sdk-android-devg-obs/obs_26_1500.html) | [iOS](https://support.huaweicloud.com/sdk-ios-devg-obs/obs_27_1500.html) | [PHP](https://support.huaweicloud.com/sdk-php-devg-obs/obs_28_1500.html) | [Node.js](https://support.huaweicloud.com/sdk-nodejs-devg-obs/obs_29_1500.html) |
|---|---|---|---|---|---|---|---|---|---|
   
#### 修改已有对象的加密状态
您可以使用**复制同名对象**的方式，将桶中已有的未加密对象更改为加密状态，或者修改对象的加密方式。
OBS支持通过API、SDK修改对象的加密方式。
#### 使用API
[复制对象](https://support.huaweicloud.com/api-obs/obs_04_0082.html)
了解更多详见[服务端加密相关接口概览](https://support.huaweicloud.com/usermanual-obs/obs_03_0094.html#ZH-CN_TOPIC_0000002384025230)。
#### 使用SDK
| [Java](https://support.huaweicloud.com/sdk-java-devg-obs/obs_21_0805.html) | [Python](https://support.huaweicloud.com/sdk-python-devg-obs/obs_22_0917.html) | [C](https://support.huaweicloud.com/sdk-c-devg-obs/obs_20_0605.html) | [Go](https://support.huaweicloud.com/sdk-go-devg-obs/obs_33_0505.html) | [BrowserJS](https://support.huaweicloud.com/sdk-browserjs-devg-obs/obs_24_0705.html) | [.NET](https://support.huaweicloud.com/sdk-dotnet-devg-obs/obs_25_0605.html) | [Android](https://support.huaweicloud.com/sdk-android-devg-obs/obs_26_0605.html) | [iOS](https://support.huaweicloud.com/sdk-ios-devg-obs/obs_27_0605.html) | [PHP](https://support.huaweicloud.com/sdk-php-devg-obs/obs_28_0605.html) | [Node.js](https://support.huaweicloud.com/sdk-nodejs-devg-obs/obs_29_0608.html) |
|---|---|---|---|---|---|---|---|---|---|
   
#### 相关文档
- 当您使用SSE-KMS对海量对象进行加密时，每个对象的加密过程都需要OBS调用KMS服务来派生数据加密密钥，这可能会导致大量的请求发送到KMS，从而产生时延和大量的KMS访问流量。为了减少对KMS的请求量，您可以使用桶密钥功能减少与KMS的交互次数，降低加解密操作对KMS的流量需求，从而节约成本，提高性能。了解更多请参考[使用OBS桶密钥降低SSE-KMS成本](https://support.huaweicloud.com/usermanual-obs/obs_03_0091.html#ZH-CN_TOPIC_0000002383865354)。
 
#### CMK类型是选择默认密钥还是自定义密钥？
以下情况请考虑使用**默认密钥**：
- 上传或下载对象的IAM用户，与默认密钥都归属于同一个华为云账号
- 您不希望管理CMK。
以下情况请考虑使用**自定义密钥**：
- 您希望对CMK进行创建、轮转、禁用密钥或定义其访问控制等操作。
- 您希望其他账号对OBS对象的访问权限，此时需要为其他账号授予自定义密钥的访问权限。
 
