

# Athena 的数据保护
<a name="security-data-protection"></a>

AWS [责任共担模式](https://aws.amazon.com/compliance/shared-responsibility-model/)适用于中的数据保护。如该模式中所述，AWS 负责保护运行所有 AWS 云 的全球基础架构。您负责维护对托管在此基础结构上的内容的控制。您还负责您所使用的 AWS 服务 的安全配置和管理任务。有关数据隐私的更多信息，请参阅[数据隐私常见问题](https://aws.amazon.com/compliance/data-privacy-faq/)。有关欧洲数据保护的信息，请参阅 *AWS Security Blog* 上的 [AWS Shared Responsibility Model and GDPR](https://aws.amazon.com/blogs/security/the-aws-shared-responsibility-model-and-gdpr/) 博客文章。

出于数据保护目的，建议您保护 AWS 账户 凭证并使用 AWS IAM Identity Center 或 AWS Identity and Access Management（IAM）设置单个用户。这样，每个用户只获得履行其工作职责所需的权限。还建议您通过以下方式保护数据：
+ 对每个账户使用多重身份验证（MFA）。
+ 使用 SSL/TLS 与 AWS 资源进行通信。我们要求使用 TLS 1.2，建议使用 TLS 1.3。
+ 使用 AWS CloudTrail 设置 API 和用户活动日记账记录。有关使用 CloudTrail 跟踪来捕获 AWS 活动的信息，请参阅《AWS CloudTrail 用户指南》**中的[使用 CloudTrail 跟踪](https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudtrail-trails.html)。
+ 使用 AWS 加密解决方案以及 AWS 服务中的所有默认安全控制。
+ 使用高级托管安全服务（例如 Amazon Macie），它有助于发现和保护存储在 Amazon S3 中的敏感数据。
+ 如果在通过命令行界面或 API 访问 AWS 时需要经过 FIPS 140-3 验证的加密模块，请使用 FIPS 端点。有关可用的 FIPS 端点的更多信息，请参阅《美国联邦信息处理标准（FIPS）第 140-3 版》[https://aws.amazon.com/compliance/fips/](https://aws.amazon.com/compliance/fips/)。

强烈建议您切勿将机密信息或敏感信息（如您客户的电子邮件地址）放入标签或自由格式文本字段（如**名称**字段）。这包括使用控制台、API、AWS CLI 或 AWS SDK 处理或其他 AWS 服务 时。在用于名称的标签或自由格式文本字段中输入的任何数据都可能会用于计费或诊断日志。如果您向外部服务器提供 URL，强烈建议您不要在网址中包含凭证信息来验证对该服务器的请求。

作为额外的安全步骤，您可以使用 [https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_condition-keys.html#condition-keys-calledvia](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_condition-keys.html#condition-keys-calledvia) 全局条件上下文键将请求限制为仅从 Athena 发出的请求。有关更多信息，请参阅 [使用适用于 Athena 的 CalledVia 上下文密钥](security-iam-athena-calledvia.md)。

## 保护多种类型的数据
<a name="security-data-protection-types-of-data"></a>

当您使用 Athena 创建数据库和表时，涉及多种类型的数据。这些数据类型包括 Amazon S3 中存储的源数据、在运行查询或 AWS Glue Crawler 以发现数据时创建的数据库和表的元数据、查询结果数据，以及查询历史记录。本部分介绍每种类型的数据并提供有关保护数据的指导。
+ **源数据** – 您在 Amazon S3 中存储数据库和表的数据，并且 Athena 不会修改这些数据。有关更多信息，请参阅《Amazon Simple Storage Service 用户指南**》中的 [Amazon S3 中的数据保护](https://docs.aws.amazon.com/AmazonS3/latest/userguide/DataDurability.html)。您可以控制对您的源数据的访问并在 Amazon S3 中加密这些数据。您可以使用 Athena，[在 Amazon S3 中根据加密的数据集创建表](creating-tables-based-on-encrypted-datasets-in-s3.md)。
+ **数据库和表元数据（架构）** – Athena 使用基于读取的架构技术，这意味着当 Athena 运行查询时，表定义将应用于 Amazon S3 中的数据。您定义的任何架构都会自动保存，除非明确将其删除。在 Athena 中，您可以使用 DDL 语句修改 Data Catalog 元数据。您还可以删除表定义和架构，这不会影响存储在 Amazon S3 上的基础数据。在 Athena 中使用的数据库和表元数据存储在 AWS Glue Data Catalog 中。

  您可以使用 AWS Identity and Access Management (IAM) [定义针对在 AWS Glue Data Catalog 中注册的数据库和表的精细访问策略](fine-grained-access-to-glue-resources.md)。您还可以[对 AWS Glue Data Catalog 中的元数据进行加密](https://docs.aws.amazon.com/glue/latest/dg/encrypt-glue-data-catalog.html)。如果您加密元数据，请使用[对加密元数据的权限](encryption.md#glue-encryption)进行访问。
+ **查询结果和查询历史记录，包括保存的查询** - 查询结果存储在 Amazon S3 位置中，您可以选择全局指定该位置，或者为每个工作组指定该位置。如果未指定，Athena 在每个案例中使用默认位置。您可以控制对 Amazon S3 存储桶的访问，您在这些存储桶中存储查询结果和保存的查询。此外，您可以选择加密在 Amazon S3 中存储的查询结果。您的用户必须拥有适当的权限，才能访问 Amazon S3 位置并解密文件。有关更多信息，请参阅本文档中的[加密在 Amazon S3 中存储的 Athena 查询结果](encrypting-query-results-stored-in-s3.md)。

  Athena 保留查询历史记录 45 天。您可以在控制台中使用 Athena API [查看查询历史记录](queries-viewing-history.md)，或者使用 AWS CLI 查看。要将查询存储超过 45 天时间，请保存查询。要保护对已保存查询的访问，在 Athena 中[使用工作组](workgroups-manage-queries-control-costs.md)，限制仅有权查看已保存查询的用户才能访问。

**Topics**
+ [保护多种类型的数据](#security-data-protection-types-of-data)
+ [静态加密](encryption.md)
+ [传输中加密](encryption-in-transit.md)
+ [密钥管理](key-management.md)
+ [互联网络流量隐私](internetwork-traffic-privacy.md)

# 静态加密
<a name="encryption"></a>

您可以在 Amazon Athena 中针对同一区域或有限数量的区域中 Amazon S3 中的加密数据运行查询。您还可以加密 Amazon S3 中的查询结果以及 AWS Glue Data Catalog 中的数据。

您可以对 Athena 中的以下资产进行加密：
+ Amazon S3 中所有查询的结果，Athena 将这些结果存储在称为 Amazon S3 结果位置的位置中。您可以加密在 Amazon S3 中存储的查询结果，无论底层数据集是否在 Amazon S3 中加密都是如此。有关信息，请参阅[加密在 Amazon S3 中存储的 Athena 查询结果](encrypting-query-results-stored-in-s3.md)。
+ AWS Glue 数据目录中的数据。有关信息，请参阅[针对 AWS Glue 数据目录中加密元数据的权限](#glue-encryption)。

**注意**  
使用 Athena 读取加密的表时，Athena 使用为表数据指定的加密选项，而不是查询结果的加密选项。如果为查询结果和表数据配置了单独的加密方法或密钥，Athena 将读取表数据，而不使用加密选项和用于加密或解密查询结果的密钥。  
但是，如果使用 Athena 将数据插入到具有加密数据的表中，则 Athena 将使用为查询结果指定的加密配置来加密插入的数据。例如，如果您为查询结果指定 `CSE_KMS` 加密，则 Athena 将使用与用于查询结果加密的相同 AWS KMS 密钥 ID，通过 `CSE_KMS` 对插入的表数据进行加密。

**Topics**
+ [支持的 Amazon S3 加密选项](#encryption-options-S3-and-Athena)
+ [Amazon S3 中加密数据的权限](#permissions-for-encrypting-and-decrypting-data)
+ [针对 AWS Glue 数据目录中加密元数据的权限](#glue-encryption)
+ [从 CSE-KMS 迁移到 SSE-KMS](migrating-csekms-ssekms.md)
+ [加密在 Amazon S3 中存储的 Athena 查询结果](encrypting-query-results-stored-in-s3.md)
+ [根据 Amazon S3 中的加密数据集创建表](creating-tables-based-on-encrypted-datasets-in-s3.md)

## 支持的 Amazon S3 加密选项
<a name="encryption-options-S3-and-Athena"></a>

Athena 支持 Amazon S3 中数据集和查询结果的以下加密选项。


| 加密类型 | 说明 | 跨区域支持 | 
| --- | --- | --- | 
| [SSE-S3](https://docs.aws.amazon.com/AmazonS3/latest/userguide/UsingServerSideEncryption.html) | 使用 Amazon S3 托管式密钥进行服务器端加密 (SSE)。 | 是 | 
| [SSE-KMS](https://docs.aws.amazon.com/AmazonS3/latest/userguide/UsingKMSEncryption.html)（推荐） | 使用 AWS Key Management Service 客户自主管理型密钥进行服务器端加密（SSE）。 | 是 | 
| [CSE-KMS](https://docs.aws.amazon.com/AmazonS3/latest/userguide/UsingClientSideEncryption.html#client-side-encryption-kms-managed-master-key-intro) |  使用 AWS KMS 客户管理的密钥进行客户端加密 (CSE)。在 Athena 中，此选项要求您使用带有 `TBLPROPERTIES` 子句的 `CREATE TABLE` 语句，指定 `'has_encrypted_data'='true'` 或 `'encryption_option'='CSE_KMS'` 及 `'kms_key'='kms_key_arn'`。有关更多信息，请参阅 [根据 Amazon S3 中的加密数据集创建表](creating-tables-based-on-encrypted-datasets-in-s3.md)。  | 否 | 

有关使用 Amazon S3 进行 AWS KMS 加密的更多信息，请参阅《AWS Key Management Service 开发人员指南**》中的 [什么是 AWS Key Management Service](https://docs.aws.amazon.com/kms/latest/developerguide/overview.html) 和 [Amazon Simple Storage Service (Amazon S3) 如何使用 AWS KMS](https://docs.aws.amazon.com/kms/latest/developerguide/services-s3.html)。有关使用 Athena 操作 SSE-KMS 或 CSE-KMS 的更多信息，请参阅 *AWS 大数据博客*的 [启动：Amazon Athena 增加了对查询加密数据的支持](https://aws.amazon.com/blogs/aws/launch-amazon-athena-adds-support-for-querying-encrypted-data/)。

### 加密建议
<a name="encryption-recommendation"></a>

使用客户自主管理型 KMS 密钥来加密和解密表数据以及查询结果时，我们建议您使用 SSE-KMS 加密方法，而不是 SSE-S3 或 CSE-KMS 加密方法。SSE-KMS 很好地平衡了控制力、简单性和性能，因此是在使用托管式 KMS 密钥进行数据加密时的推荐方法。

**SSE-KMS 相比 SSE-S3 的优势**
+ SSE-KMS 允许您指定和管理自己的密钥，从而让您拥有更大的控制力。您可以定义密钥策略、监督密钥生命周期和监控密钥使用情况。

**SSE-KMS 相比 CSE-KMS 的优势**
+ 与 CSE-KMS 需要持续维护 S3 加密客户端不同，SSE-KMS 无需额外的基础设施来加密和解密数据。
+ 由于加密算法的不断发展，CSE-KMS 可能会面临新旧 S3 加密客户端之间的兼容性问题，而 SSE-KMS 则避免了这一问题。
+ 与 CSE-KMS 相比，SSE-KMS 在加密和解密过程中对 KMS 服务进行密钥检索的 API 调用更少，因此性能更高。

### 不支持的选项
<a name="encryption-unsupported-options"></a>

不支持以下加密选项：
+ 客户提供密钥 SSE (SSE-C)。
+ 使用客户端托管式密钥进行客户端加密。
+ 非对称密钥。

若要比较 Amazon S3 加密选项，请参阅《Amazon Simple Storage Service 用户指南**》中的 [使用加密保护数据](https://docs.aws.amazon.com/AmazonS3/latest/userguide/UsingEncryption.html)。

### 客户端加密的工具
<a name="encryption-client-side-tools"></a>

 对于客户端加密，请注意有两种工具可用：
+ [Amazon S3 加密客户端](https://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/services/s3/AmazonS3EncryptionClient.html) – 此操作工具仅加密 Amazon S3 的数据，并且受 Athena 支持。
+ [AWS Encryption SDK](https://docs.aws.amazon.com/encryption-sdk/latest/developer-guide/introduction.html) – 软件开发工具包可在 AWS 的任何地方加密数据但并不直接受 Athena 支持。

这两种工具不兼容，使用一种工具加密的数据不能用另一种工具解密。Athena 仅能直接支持 Amazon S3 加密客户端。如果您使用软件开发工具包对数据进行加密，则可以从 Athena 运行查询，但数据将作为加密文本返回。

如果要使用 Athena 查询已使用 AWS 加密软件开发工具包加密的数据，您必须下载并解密您的数据，然后使用 Amazon S3 加密客户端再次对其加密。

## Amazon S3 中加密数据的权限
<a name="permissions-for-encrypting-and-decrypting-data"></a>

根据在 Amazon S3 中使用的加密类型，可能需要向 Athena 中使用的策略添加权限（也称为“允许”操作）：
+ **SSE-S3** - 如果使用 SSE-S3 加密，则 Athena 用户无需在其策略中添加权限。对相应的 Amazon S3 位置和 Athena 操作具有适当的 Amazon S3 权限就足够了。要详细了解允许适当 Athena 和 Amazon S3 权限的策略，请参阅[Amazon Athena 的 AWS 托管策略](security-iam-awsmanpol.md)和 [控制从 Athena 对 Amazon S3 的访问](s3-permissions.md)。
+ **AWS KMS** - 如果使用 AWS KMS 加密，则除了 Athena 和 Amazon S3 权限之外，还必须允许 Athena 用户执行特定 AWS KMS 操作。您可以通过编辑用于加密 Amazon S3 中数据的客户自主管理型密钥的密钥策略来允许这些操作。要将密钥用户添加到相应的 AWS KMS 密钥策略，则可以使用 AWS KMS 控制台，网址：[https://console.aws.amazon.com/kms](https://console.aws.amazon.com/kms)。有关如何将用户添加到 AWS KMS 密钥策略，请参阅《*AWS Key Management Service 开发人员指南*》中的[允许密钥用户使用客户自主管理型密钥](https://docs.aws.amazon.com/kms/latest/developerguide/key-policies.html#key-policy-default-allow-users)。
**注意**  
高级密钥策略管理员可以调整密钥策略。要处理加密数据集，最少应允许 Athena 用户执行 `kms:Decrypt` 操作。要使用加密的查询结果，则最小允许操作是 `kms:GenerateDataKey` 和 `kms:Decrypt`。

  使用 Athena 查询 Amazon S3 中数据集时，如果该数据集具有大量使用 AWS KMS 加密的对象，则 AWS KMS 可能会对查询结果进行节流。当有大量的小对象时，这种可能性更大。Athena 已停止重试请求，但可能仍会发生节流错误。如果您在处理大量加密对象时遇到此问题，则可以选择启用 Amazon S3 存储桶密钥来减少对 KMS 的调用次数。有关更多信息，请参阅《Amazon Simple Storage Service 用户指南**》中的 [使用 Amazon S3 存储桶密钥降低 SSE-KMS 的成本](https://docs.aws.amazon.com/AmazonS3/latest/userguide/bucket-key.html)。另一种选择是增加 AWS KMS 的服务配额。有关更多信息，请参阅《*AWS Key Management Service 开发人员指南*》中的[配额](https://docs.aws.amazon.com/kms/latest/developerguide/limits.html#requests-per-second)。

有关将 Amazon S3 与 Athena 结合使用时的权限疑难解答信息，请参阅 [在 Athena 中进行排查问题](troubleshooting-athena.md) 主题的 [权限](troubleshooting-athena.md#troubleshooting-athena-permissions) 部分。

## 针对 AWS Glue 数据目录中加密元数据的权限
<a name="glue-encryption"></a>

如果[加密 AWS Glue Data Catalog 中的元数据](https://docs.aws.amazon.com/glue/latest/dg/encrypt-glue-data-catalog.html)，则必须向用于访问 Athena 的策略添加 `"kms:GenerateDataKey"`、`"kms:Decrypt"` 和 `"kms:Encrypt"` 操作。有关信息，请参阅[从 Athena 配置对 AWS Glue Data Catalog 中加密元数据的访问](access-encrypted-data-glue-data-catalog.md)。

# 从 CSE-KMS 迁移到 SSE-KMS
<a name="migrating-csekms-ssekms"></a>

您可以通过以下两种方式指定 CSE-KMS 加密：在工作组查询结果加密配置过程中以及在客户端设置中。有关更多信息，请参阅 [加密在 Amazon S3 中存储的 Athena 查询结果](encrypting-query-results-stored-in-s3.md)。在迁移过程中，务必要审计读写 CSE-KMS 数据的现有工作流，确定配置了 CSE-KMS 的工作组，并找到通过客户端参数设置了 CSE-KMS 的实例。

## 更新工作组查询结果加密设置
<a name="migrating-updating-workgroup-query-results-encryption"></a>

------
#### [ Console ]

**在 Athena 控制台中更新加密设置**

1. 从 [https://console.aws.amazon.com/athena/](https://console.aws.amazon.com/athena/) 打开 Athena 控制台。

1. 在 Athena 控制台导航窗格中，选择 **Workgroups**（工作组）。

1. 在 **Workgroups**（工作组）页面上，选择要编辑的工作组的按钮。

1. 选择 **Actions**（操作）和 **Edit**（编辑）。

1. 打开**查询结果配置**，然后选择**加密查询结果**。

1. 对于**加密类型**部分，选择 **SSE\$1KMS** 加密选项。

1. 在**选择其他 AWS KMS 密钥（高级）**下，输入您的 KMS 密钥。

1. 选择**保存更改**。已更新的工作组显示在 **Workgroups **（工作组）页面上的列表中。

------
#### [ CLI ]

运行以下命令，将查询结果加密配置更新为工作组中的 SSE-KMS。

```
aws athena update-work-group \
    --work-group "my-workgroup" \
    --configuration-updates '{
        "ResultConfigurationUpdates": {
            "EncryptionConfiguration": {
                "EncryptionOption": "SSE_KMS",
                "KmsKey": "<my-kms-key>"
            }
        }
    }'
```

------

## 更新客户端查询结果加密设置
<a name="migrating-updating-clientside-query-results-encryption"></a>

------
#### [ Console ]

要将客户端查询结果加密设置从 CSE-KMS 更新为 SSE-KMS，请参阅[加密在 Amazon S3 中存储的 Athena 查询结果](encrypting-query-results-stored-in-s3.md)。

------
#### [ CLI ]

您只能使用 `start-query-execution` 命令在客户端设置中指定查询结果加密配置。如果您运行此 CLI 命令并覆盖您在工作组中使用 CSE-KMS 指定的查询结果加密配置，请按如下所示，更改命令以使用 `SSE_KMS` 加密查询结果。

```
aws athena start-query-execution \
    --query-string "SELECT * FROM <my-table>;" \
    --query-execution-context "Database=<my-database>,Catalog=<my-catalog>" \
    --result-configuration '{
        "EncryptionConfiguration": {
            "EncryptionOption": "SSE_KMS",
            "KmsKey": "<my-kms-key>"
        }
    }' \
    --work-group "<my-workgroup>"
```

------

**注意**  
更新工作组或客户端设置后，通过写查询插入的任何新数据都将使用 SSE-KMS 加密，而不是 CSE-KMS 加密。这是因为查询结果加密配置也会应用到新插入的表数据。Athena 查询结果、元数据和清单文件也使用 SSE-KMS 进行加密。
即使混合了 CSE-KMS 加密对象和 SSE-S3/SSE-KMS 对象，Athena 仍然可以读取具有 `has_encrypted_data` 表属性的表。

# 将 CSE-KMS 表格数据转换为 SSE-KMS
<a name="convert-csekms-table-ssekms"></a>

如果您的工作流当前使用 CSE-KMS 进行表数据加密，请按照以下步骤过渡到 SSE-KMS。

## 先决条件
<a name="convert-csekms-table-ssekms-preq"></a>

如果您仍在使用 CSE-KMS 工作组或客户端设置写入数据，请按照[从 CSE-KMS 迁移到 SSE-KMS](migrating-csekms-ssekms.md)中的步骤将其更新为 SSE-KMS。这样可以防止在迁移过程中从任何其他可能写入表的工作流中添加新的 CSE-KMS 加密数据。

## 数据迁移
<a name="convert-csekms-table-ssekms-migrat"></a>

1. 检查表的 `has_encrypted_data` 属性是否设置为 `true`。此属性指定该表可能包含 CSE-KMS 加密数据。但需要注意的是，即使表中没有任何实际的 CSE-KMS 加密数据，也可能存在此属性。

------
#### [ Console ]

   1. 从 [https://console.aws.amazon.com/athena/](https://console.aws.amazon.com/athena/) 打开 Athena 控制台。

   1. 选择**启动查询编辑器**。

   1. 在编辑器左侧的**数据库**下，选择要查询的数据库。

   1. 在查询编辑器中，运行以下查询来查看为 `has_encrypted_data table` 属性设置的值。

      ```
      SHOW TBLPROPERTIES <table_name>('has_encrypted_data');
      ```

------
#### [ CLI ]

   启动将显示表中 `has_encrypted_data` 属性值的 Athena 查询，如以下示例所示。

   ```
   aws athena start-query-execution \
       --query-string "SHOW TBLPROPERTIES <table-name>('has_encrypted_data');" \
       --work-group "<my-workgroup>"
   ```

   获取查询结果以查看表的 `has_encrypted_data` 表属性值，如以下示例所示。

   ```
   aws athena get-query-results --query-execution-id <query-execution-id-from-previous-step>
   ```

------

1. 对于表中的每个 CSE-KMS 加密对象。

   1. 使用 S3 加密客户端从 S3 下载该对象并将其解密。以下是一个使用 AWS Java SDK V2 的示例。

      **导入**

      ```
      import software.amazon.awssdk.core.ResponseInputStream;
      import software.amazon.awssdk.services.s3.model.GetObjectRequest;
      import software.amazon.awssdk.services.s3.model.GetObjectResponse;
      import software.amazon.encryption.s3.S3EncryptionClient;
      import software.amazon.encryption.s3.materials.Keyring;
      import software.amazon.encryption.s3.materials.KmsDiscoveryKeyring;
      ```

      代码

      ```
      final Keyring kmsDiscoveryKeyRing = KmsDiscoveryKeyring.builder()
              .enableLegacyWrappingAlgorithms(true)
              .build();
      final S3EncryptionClient s3EncryptionClient = S3EncryptionClient.builder()
              .enableLegacyUnauthenticatedModes(true)
              .keyring(kmsDiscoveryKeyRing)
              .build();
      
      GetObjectRequest getObjectRequest = GetObjectRequest.builder()
              .bucket("amzn-s3-demo-bucket")
              .key("<my-key>")
              .build();
      
      ResponseInputStream<GetObjectResponse> s3Object = s3EncryptionClient.getObject(getObjectRequest);
      ```

   1. 使用相同的名称和 SSE-KMS 加密将该对象上传到 S3。以下是一个使用 AWS Java SDK V2 的示例。

      **导入**

      ```
      import software.amazon.awssdk.core.ResponseInputStream;
      import software.amazon.awssdk.core.sync.RequestBody;
      import software.amazon.awssdk.services.s3.S3Client;
      import software.amazon.awssdk.services.s3.model.PutObjectRequest;
      import software.amazon.awssdk.services.s3.model.ServerSideEncryption;
      ```

      **代码**

      ```
      final S3Client s3Client = S3Client.builder()
              .build();
                  
      PutObjectRequest putObjectRequest = PutObjectRequest.builder()
              .bucket("amzn-s3-demo-bucket")
              .key("<my-key>")
              .serverSideEncryption(ServerSideEncryption.AWS_KMS)
              .ssekmsKeyId("<my-kms-key>")
              .build();
      
      s3Client.putObject(putObjectRequest, RequestBody.fromBytes(s3Object.readAllBytes()));
      ```

## 迁移后
<a name="convert-csekms-table-ssekms-post-migrat"></a>

成功重新加密表中的所有 CSE-KMS 文件后，请执行以下步骤。

1. 移除表中的 `has_encrypted_data` 属性。

------
#### [ Console ]

   1. 从 [https://console.aws.amazon.com/athena/](https://console.aws.amazon.com/athena/) 打开 Athena 控制台。

   1. 选择**启动查询编辑器**。

   1. 在编辑器左侧的**数据库**下，选择要查询的数据库。

   1. 在查询编辑器中，对表运行以下查询。

      ```
      ALTER TABLE <database-name>.<table-name> UNSET TBLPROPERTIES ('has_encrypted_data')
      ```

------
#### [ CLI ]

   运行以下命令，移除表中的 `has_encrypted_data` 属性。

   ```
   aws athena start-query-execution \
       --query-string "ALTER TABLE <database-name>.<table-name> UNSET TBLPROPERTIES ('has_encrypted_data');" \
       --work-group "<my-workgroup>"
   ```

------

1. 更新工作流以使用基本 S3 客户端而不是 S3 加密客户端，然后为数据写入指定 SSE-KMS 加密。

# 加密在 Amazon S3 中存储的 Athena 查询结果
<a name="encrypting-query-results-stored-in-s3"></a>

使用 Athena 控制台或使用 JDBC 或 ODBC 时设置查询结果加密。使用工作组可以强制对查询结果实施加密。

**注意**  
加密查询结果时，Athena 会加密由查询写入的所有对象。这包括 `INSERT INTO` 和 `UPDATE` 等语句以及对 Iceberg 或其他格式数据的查询结果。

在控制台中，您可以通过两种方式配置对查询结果加密的设置：
+ **客户端设置** - 当您在控制台中使用 **Settings**（设置） 或者 API 操作来指示您希望加密查询结果时，这称为使用客户端设置。客户端设置包括查询结果位置和加密。如果您指定这些内容，则除非工作组设置进行覆盖，否则将使用它们。
+ **Workgroup settings**（工作组设置）– 当您[创建或编辑工作组](creating-workgroups.md)并选择 **Override client-side settings**（覆盖客户端设置）字段时，此工作组中运行的所有查询均使用工作组设置和查询结果位置设置。有关更多信息，请参阅 [Override client-side settings (覆盖客户端设置)](workgroups-settings-override.md)。

**使用控制台加密在 Amazon S3 中存储的查询结果**
**重要**  
如果工作组中的 **Override client-side settings**（覆盖客户端设置）字段已被选中，则工作组中的所有查询均使用工作组设置。不使用通过 Athena 控制台的**设置**选项卡、API 操作及 JDBC 和 ODBC 驱动程序指定的加密配置和查询结果位置。有关更多信息，请参阅 [Override client-side settings (覆盖客户端设置)](workgroups-settings-override.md)。

1. 在 Athena 控制台中，选择 **Settings**（设置）。  
![\[Athena 查询编辑器的设置选项卡。\]](http://docs.aws.amazon.com/zh_cn/athena/latest/ug/images/settings.png)

1. 选择**管理**。

1. 在 **Location of query result**（查询结果位置）中，输入或选择 Amazon S3 路径。这是存储查询结果的 Amazon S3 位置。

1. 选择 **Encrypt query results**。  
![\[Athena 控制台管理设置页面上的加密查询结果选项。\]](http://docs.aws.amazon.com/zh_cn/athena/latest/ug/images/encrypt-query-results.png)

1. 对于 **Encryption type**，选择 **CSE-KMS**、**SSE-KMS** 或 **SSE-S3**。在这三者中，**CSE-KMS** 提供的加密级别最高，**SSE-S3** 提供的加密级别最低。

1. 如果您选择了 **SSE-KMS** 或 **CSE-KMS**，则指定 AWS KMS 密钥。
   + 对于**选择 AWS KMS 密钥**，如果您的账户有权访问某个现有 AWS KMS 客户自主管理型密钥，请选择其别名或输入 AWS KMS 密钥 ARN。
   +  如果您的账户无权访问某个现有的客户自主管理型密钥，请选择**创建 AWS KMS 密钥**，然后打开 [AWS KMS 控制台](https://console.aws.amazon.com/kms)。有关更多信息，请参阅 *AWS Key Management Service 开发人员指南*中的[创建密钥](https://docs.aws.amazon.com/kms/latest/developerguide/create-keys.html)。
**注意**  
Athena 仅支持读取和写入数据的对称密钥。

1. 返回 Athena 控制台，选择您通过别名或 ARN 创建的密钥。

1. 选择**保存**。

## 使用 JDBC 或 ODBC 时对 Athena 查询结果进行加密
<a name="encrypting-query-results-stored-in-s3-jdbc-odbc"></a>

如果您使用 JDBC 或 ODBC 驱动程序进行连接，请配置驱动程序选项来指定要使用的加密类型以及 Amazon S3 暂存目录位置。要配置 JDBC 或 ODBC 驱动程序以使用 Athena 支持的任何加密协议加密查询结果，请参阅[通过 ODBC 和 JDBC 驱动程序连接到 Amazon Athena](athena-bi-tools-jdbc-odbc.md)。

# 根据 Amazon S3 中的加密数据集创建表
<a name="creating-tables-based-on-encrypted-datasets-in-s3"></a>

Athena 可以读取和写入底层数据集采用 SSE-S3、SSE-KMS 或 CSE-KMS 加密的表。根据表数据使用的加密选项和运行的查询类型，您可能需要指定一些其他表属性才能读取和写入加密数据。

## 读取 SSE-S3/SSE-KMS 加密表
<a name="reading-sse-s3-sse-kms-encrypted-tables"></a>

创建表时无需指定其他表属性即可读取 SSE-S3/SSE-KMS 加密数据集。Amazon S3 会自动处理 SSE 对象的解密。

## 读取 CSE-KMS 加密表
<a name="reading-cse-kms-encrypted-tables"></a>

为使 Athena 能够读取 CSE-KMS 加密数据集，可以指定两组不同的表属性：
+ 使用 `encryption_option` 和 `kms_key` 表属性（推荐）
+ 使用 `has_encrypted_data` 表属性

**重要**  
如果使用 Amazon EMR 以及 EMRFS 上传 CSE-KMS 加密的 Parquet 文件，则必须通过将 `fs.s3n.multipart.uploads.enabled` 设置为 `false` 来禁用分段上传。如果您未执行此操作，则 Athena 无法确定 Parquet 文件长度，将出现 **HIVE\$1CANNOT\$1OPEN\$1SPLIT** 错误。有关更多信息，请参阅《Amazon EMR 管理指南》**中的[为 Amazon S3 配置分段上传](https://docs.aws.amazon.com/emr/latest/ManagementGuide/emr-plan-upload-s3.html#Config_Multipart)。

### 使用 encryption\$1option 和 kms\$1key 表属性
<a name="using-encryption-option-and-kms-key-table-properties"></a>

在 [CREATE TABLE](create-table.md) 语句中，请使用 `TBLPROPERTIES` 子句指定 `encryption_option='CSE_KMS'` 和 `kms_key='aws_kms_key_arn'`，如以下示例所示。

```
CREATE EXTERNAL TABLE 'my_encrypted_data' (
   `n_nationkey` int,
   `n_name` string,
   `n_regionkey` int,
   `n_comment` string)
ROW FORMAT SERDE
   'org.apache.hadoop.hive.ql.io.parquet.serde.ParquetHiveSerDe'
STORED AS INPUTFORMAT
   'org.apache.hadoop.hive.ql.io.parquet.MapredParquetInputFormat'
LOCATION
   's3://amzn-s3-demo-bucket/folder_with_my_encrypted_data/'
TBLPROPERTIES (
    'encryption_option' = 'CSE_KMS',
    'kms_key' = 'arn:aws:kms:us-east-1:012345678901:key/my_kms_key')
```

配置这些属性后：
+ Athena 可以读取由 V1、V2 或 V3 Amazon S3 加密客户端创建的 CSE-KMS 加密对象。
+ Athena 将使用 `kms_key` 中的 AWS KMS 密钥来解密 CSE-KMS 数据。如果任何对象使用不同的 AWS KMS 密钥加密，则查询将失败。
+ Athena 仍然可以读取 SSE-S3 和 SSE-KMS 加密对象，但不建议混合使用服务器端和客户端加密对象。

### 使用 has\$1encrypted\$1data 表属性
<a name="using-has-encrypted-data-table-property"></a>

在 [CREATE TABLE](create-table.md) 语句，请使用 `TBLPROPERTIES` 子句指定 `has_encrypted_data='true'`，如以下示例所示。

```
CREATE EXTERNAL TABLE 'my_encrypted_data' (
   `n_nationkey` int,
   `n_name` string,
   `n_regionkey` int,
   `n_comment` string)
ROW FORMAT SERDE
   'org.apache.hadoop.hive.ql.io.parquet.serde.ParquetHiveSerDe'
STORED AS INPUTFORMAT
   'org.apache.hadoop.hive.ql.io.parquet.MapredParquetInputFormat'
LOCATION
   's3://amzn-s3-demo-bucket/folder_with_my_encrypted_data/'
TBLPROPERTIES (
    'has_encrypted_data' = 'true')
```

指定 has\$1encrypted\$1data 表属性时：
+ Athena 只能读取由 V1 Amazon S3 加密客户端创建的 CSE-KMS 加密对象。
+ Athena 将从对象元数据中推断出用于加密 CSE-KMS 对象的 AWS KMS 密钥，然后使用该密钥解密对象。
+ Athena 仍然可以读取 SSE-S3 和 SSE-KMS 加密对象，但不建议混合使用服务器端和客户端加密对象。

**注意**  
当 `encryption_option` 和 `kms_key` 与 `has_encrypted_data` 同时指定时，`encryption_option` 和 `kms_key` 表属性优先，而 `has_encrypted_data` 将被忽略。

使用 Athena 控制台[使用表单创建表](data-sources-glue-manual-table.md)并指定表位置时，请选择**加密的数据集**选项，将 `has_encrypted_data='true'` 属性添加到表格。

![\[在添加表单项中选择 Encrypted data set（加密的数据集）\]](http://docs.aws.amazon.com/zh_cn/athena/latest/ug/images/add-table-form-encrypted-option.png)


在 Athena 控制台的表列表中，CSE-KMS 加密的表含有 `has_encrypted_data='true'`，显示钥匙形图标。

![\[加密表图标\]](http://docs.aws.amazon.com/zh_cn/athena/latest/ug/images/tables-list-encrypted-table-icon.png)


## 写入 SSE-S3/SSE-KMS/CSE-KMS 加密数据
<a name="writing-sse-s3-sse-kms-cse-kms-encrypted-data"></a>

默认情况下，新插入的数据文件将使用 Athena 工作组中指定的查询结果加密配置进行加密。要使用与查询结果加密配置不同的加密配置来写入表数据，必须添加一些其他表属性。

在 [CREATE TABLE](create-table.md) 语句中，请使用 `TBLPROPERTIES` 子句指定 `encryption_option='SSE_S3 | SSE_KMS | CSE_KMS'` 和 `kms_key='aws_kms_key_arn'`，如以下示例所示。

```
CREATE EXTERNAL TABLE 'my_encrypted_data' (
   `n_nationkey` int,
   `n_name` string,
   `n_regionkey` int,
   `n_comment` string)
ROW FORMAT SERDE
   'org.apache.hadoop.hive.ql.io.parquet.serde.ParquetHiveSerDe'
STORED AS INPUTFORMAT
   'org.apache.hadoop.hive.ql.io.parquet.MapredParquetInputFormat'
LOCATION
   's3://amzn-s3-demo-bucket/folder_with_my_encrypted_data/'
TBLPROPERTIES (
    'encryption_option' = 'SSE_KMS',
    'kms_key' = 'arn:aws:kms:us-east-1:012345678901:key/my_kms_key')
```

所有新插入的数据都将使用表属性指定的加密配置进行加密，而不是使用工作组中查询结果的加密配置。

## 注意事项和限制
<a name="considerations-and-limitations"></a>

写入和读取加密数据集时，请考虑以下几点。
+ `has_encrypted_data`、`encryption_option` 和 `kms_key` 表属性只能用于 Hive 表。
+ 创建包含 CSE-KMS 加密数据的表时，我们建议您确保使用相同的 AWS KMS 密钥加密所有数据。
+ 创建包含 CSE-KMS 加密数据的表时，我们建议您确保所有数据均采用 CSE-KMS 加密，不混合使用非 CSE-KMS 和 CSE-KMS 加密对象。

# 传输中加密
<a name="encryption-in-transit"></a>

除了对 Amazon S3 中的数据静态加密，Amazon Athena 还对 Athena 与 Amazon S3 之间、以及 Athena 与访问它的客户应用程序之间的传输中数据使用传输层安全性 (TLS) 加密。

您应该在 Amazon S3 存储桶 IAM 策略上使用 [https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements_condition_operators.html#Conditions_Boolean](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements_condition_operators.html#Conditions_Boolean)，以只允许通过 HTTPS (TLS) 的加密连接。

流式传输到 JDBC 或 ODBC 客户端的查询结果使用 TLS 进行加密。有关最新版本的 JDBC 和 ODBC 驱动程序及其文档的信息，请参阅[通过 JDBC 连接到 Amazon Athena](connect-with-jdbc.md)和[通过 ODBC 连接到 Amazon Athena](connect-with-odbc.md)。

对于 Athena 联合数据来源连接器，是否支持使用 TLS 进行传输中加密取决于各个连接器。有关信息，请参阅各个[数据来源连接器](connectors-available.md)的文档。

# 密钥管理
<a name="key-management"></a>

Amazon Athena 支持使用 AWS Key Management Service (AWS KMS) 来加密 Amazon S3 和 Athena 查询结果中的数据集。AWS KMS 使用客户自主管理型密钥加密 Amazon S3 对象，并依赖于[信封加密](https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#enveloping)。

在 AWS KMS 中，您可以执行以下操作：
+  [创建密钥](https://docs.aws.amazon.com/kms/latest/developerguide/create-keys.html) 
+  [为新的客户自主管理型密钥导入您自己的密钥材料](https://docs.aws.amazon.com/kms/latest/developerguide/importing-keys.html) 

**注意**  
Athena 仅支持读取和写入数据的对称密钥。

有关更多信息，请参阅《AWS Key Management Service 开发人员指南**》中的[什么是 AWS Key Management Service](https://docs.aws.amazon.com/kms/latest/developerguide/overview.html) 和 [Amazon Simple Storage Service 如何使用 AWS KMS](https://docs.aws.amazon.com/kms/latest/developerguide/services-s3.html)。要查看账户中 AWS 为您创建和管理的密钥，请在导航窗格中选择 **AWS 托管式密钥**。

如果您要上载或访问使用 SSE-KMS 加密的对象，请使用 AWS 签名版本 4 来提高安全性。有关更多信息，请参阅《Amazon Simple Storage Service 用户指南**》中的 [在请求身份验证中指定签名版本](https://docs.aws.amazon.com/AmazonS3/latest/userguide/UsingAWSSDK.html#specify-signature-version)。

如果您的 Athena 工作负载加密大量数据，您可以使用 Amazon S3 存储桶密钥来降低成本。有关更多信息，请参阅《Amazon Simple Storage Service 用户指南**》中的 [使用 Amazon S3 存储桶密钥降低 SSE-KMS 的成本](https://docs.aws.amazon.com/AmazonS3/latest/userguide/bucket-key.html)。

# 互联网络流量隐私
<a name="internetwork-traffic-privacy"></a>

对 Athena 与本地应用程序之间的流量以及 Athena 与 Amazon S3 之间的流量进行保护。Athena 与其他服务（如 AWS Glue 和 AWS Key Management Service）之间的流量预设情况下使用 HTTPS。
+ **对于 Athena 与本地客户端和应用程序之间的流量**，流式传输到 JDBC 或 ODBC 客户端的查询结果使用传输层安全性 (TLS) 进行加密。

  您可以在私有网络与 AWS 之间使用以下连接选项之一：
  + 一个 Site-to-Site VPN Site-to-Site VPN 连接。有关更多信息，请参阅《*AWS Site-to-Site VPN 用户指南*》中的[什么是 Site-to-Site VPN Site-to-Site VPN](https://docs.aws.amazon.com/vpn/latest/s2svpn/VPC_VPN.html)。
  + Direct Connect 连接。有关更多信息，请参阅《[Direct Connect 用户指南](https://docs.aws.amazon.com/directconnect/latest/UserGuide/Welcome.html)》中的*什么是 Direct Connect*。
+ **对于 Athena 与 Amazon S3 存储桶之间的流量**，传输层安全性 (TLS) 会加密 Athena 和 Amazon S3 之间以及在 Athena 和访问该对象的客户应用程序之间的传输对象，您应该只允许Amazon S3 存储桶 IAM 策略上 [https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements_condition_operators.html#Conditions_Boolean](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements_condition_operators.html#Conditions_Boolean) 通过 HTTPS (TLS) 的加密连接。尽管 Athena 目前使用公有端点访问 Amazon S3 存储桶中的数据，但这并不意味着数据会遍历公共互联网。Athena 和 Amazon S3 之间的所有流量都通过 AWS 网络路由，并使用 TLS 进行加密。
+ **合规性计划** – Amazon Athena 遵守多个 AWS 合规性计划，其中包括 SOC、PCI、FedRAMP 及其他计划。有关更多信息，请参阅[合规性计划范围内的 AWS 服务](https://aws.amazon.com/compliance/services-in-scope/)。