
# 客户端加密简介(Python SDK)
客户端加密是指在传输数据前，使用您选择的加密方法与加密信息，在本地进行数据加密，再将加密后结果发送至 OBS 服务器，同时将加密方法与解密所需的必要辅助信息存储到对象元数据中。在下载时 OBS SDK 会依据您提供的密钥与存储在对象元数据中的解密辅助信息进行数据解密，直接返回解密后结果。
![](https://support.huaweicloud.com/sdk-python-devg-obs/public_sys-resources/warning_3.0-zh-cn.png)
- OBS 不会以任何方式存储您的主密钥，您必须自行保证主密钥的正确性与完整性，如果主密钥丢失或用错，将会导致您的加密后数据无法解密，OBS 不会承担任何责任。
- OBS SDK 会将解密所需的必要辅助信息存储在相应对象的元数据中，在对加密对象进行移动、复制、修改元数据等操作时，您需要保证不会修改辅助信息。如果因您删除/修改解密辅助信息而导致数据无法解密，OBS 不承担任何责任。
 
#### 加密过程与加密套件
OBS Python SDK 提供了两个不同的加密套件生成器，分别是基于 AES-CTR 加密方法的 CTRCipherGenerator 与基于 RSA + AES-CTR 加密的 CtrRSACipherGenerator。
使用 CTRCipherGenerator 上传对象时，用户需要提供一个用来加密数据的数据密钥，SDK 将会针对每个对象随机生成一个初始值，并使用数据密钥与初始值加密对象，加密完成后将加密后文件上传至 OBS，并将对应的初始值存储至对象元数据中。下载该对象时，用户需要提供对应的数据密钥，SDK 会自动获取保存在对象元数据中的初始值，使用数据密钥与初始值解密对象并返回。下载时如果提供了与加密时不同的数据密钥，SDK 也将返回不可用的解密后文件。
使用 CtrRSACipherGenerator 上传对象时，用户需要提供一个 RSA 公钥或私钥，SDK 会针对每个对象随机生成一个数据密钥和初始值，并使用数据密钥与初始值加密对象，加密完成后将加密后文件上传至 OBS，随后会使用 RSA 密钥加密数据密钥，并将加密后的数据密钥与初始值存储至对象元数据中。下载该对象时，用户需要提供同一个 RSA 公钥或私钥，SDK 会自动获取保存在对象元数据中的数据密钥与初始值，并使用公钥或私钥解密数据密钥，如果提供的公钥或私钥与上传时使用的密钥不匹配，将会抛出错误。解密成功后，SDK 将会使用解密后的数据密钥与初始值解密对象并返回。
#### 加密客户端与普通客户端的接口变更
CryptoObsClient 继承自 ObsClient，除下表所列举的接口外，其他接口均与 ObsClient 保持一致。
表1接口说明 
| 接口名                              | ObsClient 接口行为 | CryptoObsClient接口行为 |
|:---|:---|:---|
| appendObject                     | 追加上传对象         | 抛出异常                |
| copyPart                         | 复制段            | 抛出异常                |
| initiateMultipartUpload          | 初始化多段上传任务      | 抛出异常                |
| uploadPart                       | 上传段            | 抛出异常                |
| putContent                       | 流式上传或文本上传      | 将流或文本加密后上传至 OBS     |
| putFile                          | 上传普通文件至 OBS    | 将文件加密后上传至 OBS       |
| getObject                        | 普通下载文件         | 将下载文件解密后，返回解密后结果    |
| uploadFile                       | 断点续传上传文件至 OBS  | 断点续传上传加密后的文件至 OBS   |
| downloadFile                     | 断点续传下载文件至 本地   | 断点续传下载解密后的文件至本地     |
| initiateEncryptedMultipartUpload | 无              | 初始化加密多段上传任务         |
| uploadEncryptedPart              | 无              | 加密上传段               |
   
#### 元数据中的解密信息
SDK 会将解密所需的必要信息存至对象的对象自定义元数据，并且不会有其他备份，如果您对这些数据进行了修改，将会造成数据**无法解密**，需要保存的信息及其含义如下表：
表2参数名 
| 参数名                      | 约束               | 说明                          |
|:---|:---|:---|
| encrypted-algorithm      | 必选               | 加密套件的信息                     |
| encrypted-object-key     | 必选（使用 RSA 加密套件时) | 使用 RSA 密钥加密后的数据密钥           |
| encrypted-start          | 必选               | 加密该对象所使用的初始经 base64 编码后的字符串 |
| master-key-info          | 可选               | 加密密钥的信息                     |
| plaintext-sha256         | 可选               | 加密前对象的 sha256               |
| plaintext-content-length | 可选               | 加密前对象的长度                    |
| encrypted-sha256         | 可选               | 加密后对象的 sha256               |
   
