Amazon EMR
管理指南
AWS 文档中描述的 AWS 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅 Amazon AWS 入门

Amazon S3 客户端加密

对于 Amazon S3 客户端加密,Amazon S3 加密和解密在您的 EMR 集群上的 EMRFS 客户端中进行。对象在上传至 Amazon S3 之前加密,在下载后解密。您指定的提供商提供客户端使用的加密密钥。客户端可以使用 AWS KMS (CSE-KMS) 提供的密钥或使用自定义 Java 类来提供客户端主密钥 (CSE-C)。CSE-KMS 和 CSE-C 的加密细节略有不同,取决于指定的提供商以及所解密或加密对象的元数据。有关这些区别的更多信息,请参阅 Amazon Simple Storage Service Developer Guide 中的使用客户端加密保护数据

注意

Amazon S3 CSE 只确保通过 Amazon S3 交换的 EMRFS 数据是加密的,不保证集群实例卷上的所有数据都加密。此外,由于 Hue 不使用 EMRFS,因此 Hue S3 文件浏览器写入到 Amazon S3 的对象不会加密。

使用 AWS CLI 为 Amazon S3 中的 EMRFS 数据指定 CSE-KMS

  • 键入以下命令并将 MyKMSKeyID 替换为要使用的 AWS KMS CMK 的密钥 ID 或 ARN:

    aws emr create-cluster --release-label emr-4.7.2 or earlier --emrfs Encryption=ClientSide,ProviderType=KMS,KMSKeyId=MyKMSKeyId

创建自定义密钥提供商

在创建自定义密钥提供商时,应用程序应实现 EncryptionMaterialsProvider 接口,该接口在AWS SDK for Java版本 1.11.0 及更高版本中可用。该实现可使用任何策略来提供加密资料。例如,您可以选择提供静态加密资料或与一个更复杂的密钥管理系统集成。

自定义加密材料所用的加密算法必须是 AES/GCM/NoPadding

EncryptionMaterialsProvider 类按加密上下文获取加密资料。Amazon EMR 在运行时填写加密上下文信息,帮助调用方确定要返回的正确加密资料。

例 示例:对使用 EMRFS 的 Amazon S3 加密使用自定义密钥提供商

在 Amazon EMR 从 EncryptionMaterialsProvider 类提取加密资料以执行加密时,EMRFS 可通过两个字段填充 materialsDescription 参数:对象的 Amazon S3 URI 以及集群的 JobFlowId。这些字段可由 EncryptionMaterialsProvider 类使用以便有选择地返回加密资料。

例如,提供程序可以对不同 Amazon S3 URI 前缀返回不同的键。描述的是最终与 Amazon S3 对象一起存储的返回加密资料而不是由 EMRFS 生成并传递给提供程序的 materialsDescription 值。解密 Amazon S3 对象时,加密资料描述将传递给 EncryptionMaterialsProvider 类,这样它可以再次有选择地返回匹配密钥以解密对象。

下面是 EncryptionMaterialsProvider 参考实现。GitHub 提供了另一个自定义提供程序 EMRFSRSAEncryptionMaterialsProvider

import com.amazonaws.services.s3.model.EncryptionMaterials; import com.amazonaws.services.s3.model.EncryptionMaterialsProvider; import com.amazonaws.services.s3.model.KMSEncryptionMaterials; import org.apache.hadoop.conf.Configurable; import org.apache.hadoop.conf.Configuration; import java.util.Map; /** * Provides KMSEncryptionMaterials according to Configuration */ public class MyEncryptionMaterialsProviders implements EncryptionMaterialsProvider, Configurable{ private Configuration conf; private String kmsKeyId; private EncryptionMaterials encryptionMaterials; private void init() { this.kmsKeyId = conf.get("my.kms.key.id"); this.encryptionMaterials = new KMSEncryptionMaterials(kmsKeyId); } @Override public void setConf(Configuration conf) { this.conf = conf; init(); } @Override public Configuration getConf() { return this.conf; } @Override public void refresh() { } @Override public EncryptionMaterials getEncryptionMaterials(Map<String, String> materialsDescription) { return this.encryptionMaterials; } @Override public EncryptionMaterials getEncryptionMaterials() { return this.encryptionMaterials; } }

使用 AWS CLI 指定自定义材料提供商

要使用 AWS CLI,请将 EncryptionProviderTypeCustomProviderClassCustomProviderLocation 参数传递给 emrfs 选项。

aws emr create-cluster --instance-type m4.large --release-label emr-4.7.2 or earlier --emrfs Encryption=ClientSide,ProviderType=Custom,CustomProviderLocation=s3://mybucket/myfolder/provider.jar,CustomProviderClass=classname

Encryption 设置为 ClientSide 会启用客户端加密,CustomProviderClass 是您的 EncryptionMaterialsProvider 对象的名称,而 CustomProviderLocation 是本地或 Amazon S3 位置,Amazon EMR 从此位置将 CustomProviderClass 复制到集群中的每个节点并放置在类路径中。

使用开发工具包指定自定义材料提供商

要使用开发工具包,您可以设置属性 fs.s3.cse.encryptionMaterialsProvider.uri 将存储在 Amazon S3 中的自定义 EncryptionMaterialsProvider 类下载到集群中的每个节点。您在 emrfs-site.xml 文件中配置此设置,同时启用 CSE 并提供自定义提供程序的正确位置。

例如,在 AWS SDK for Java 中使用 RunJobFlowRequest 时,代码如下所示:

<snip> Map<String,String> emrfsProperties = new HashMap<String,String>(); emrfsProperties.put("fs.s3.cse.encryptionMaterialsProvider.uri","s3://mybucket/MyCustomEncryptionMaterialsProvider.jar"); emrfsProperties.put("fs.s3.cse.enabled","true"); emrfsProperties.put("fs.s3.consistent","true"); emrfsProperties.put("fs.s3.cse.encryptionMaterialsProvider","full.class.name.of.EncryptionMaterialsProvider"); Configuration myEmrfsConfig = new Configuration() .withClassification("emrfs-site") .withProperties(emrfsProperties); RunJobFlowRequest request = new RunJobFlowRequest() .withName("Custom EncryptionMaterialsProvider") .withReleaseLabel("emr-5.14.0") .withApplications(myApp) .withConfigurations(myEmrfsConfig) .withServiceRole("EMR_DefaultRole") .withJobFlowRole("EMR_EC2_DefaultRole") .withLogUri("s3://myLogUri/") .withInstances(new JobFlowInstancesConfig() .withEc2KeyName("myEc2Key") .withInstanceCount(2) .withKeepJobFlowAliveWhenNoSteps(true) .withMasterInstanceType("m4.large") .withSlaveInstanceType("m4.large") ); RunJobFlowResult result = emr.runJobFlow(request); </snip>

使用参数自定义 EncryptionMaterialsProvider

您可能需要将参数直接传递给提供程序。要执行此操作,您可以将 emrfs-site 配置分类与定义为属性的自定义参数结合使用。下面显示了一个示例配置,该示例配置将另存为 myConfig.json 文件:

[ { "Classification": "emrfs-site", "Properties": { "myProvider.arg1":"value1", "myProvider.arg2":"value2" } } ]

从 AWS CLI 中使用 create-cluster 命令,您可以使用 --configurations 选项指定文件,如下所示:

aws emr create-cluster --release-label emr-5.14.0 --instance-type m4.large --instance-count 2 --configurations file://myConfig.json --emrfs Encryption=ClientSide,CustomProviderLocation=s3://mybucket/myfolder/myprovider.jar,CustomProviderClass=classname

Amazon S3 客户端加密的 emrfs-site.xml 属性

属性 默认值 描述
fs.s3.cse.enabled false

在设置为 true 时,使用客户端加密对 Amazon S3 中存储的 EMRFS 对象进行加密。

fs.s3.cse.encryptionMaterialsProvider.uri 不适用 在使用自定义加密材料时适用。Amazon S3 URI,指向带 EncryptionMaterialsProvider 的 JAR。如果您提供此 URI,Amazon EMR 将此 JAR 自动下载到集群中的所有节点。
fs.s3.cse.encryptionMaterialsProvider 不适用

用于客户端加密的 EncryptionMaterialsProvider 类路径。在使用 CSE-KMS 时,请指定 com.amazon.ws.emr.hadoop.fs.cse.KMSEncryptionMaterialsProvider

fs.s3.cse.materialsDescription.enabled false

在设置为 true 时,请使用对象的 Amazon S3 URI 和 JobFlowId 填充加密对象的 materialsDescription。在使用自定义加密材料时设置为 true

fs.s3.cse.kms.keyId 不适用

在使用 CSE-KMS 时适用。KeyId 的值、ARN 或用于加密的 AWS KMS CMK 的别名。

fs.s3.cse.cryptoStorageMode ObjectMetadata

Amazon S3 存储模式。默认情况下,加密信息的描述存储在对象元数据中。也可以将描述存储在指令文件中。有效值为 ObjectMetadata 和 InstructionFile。有关更多信息,请参阅 Client-Side Data Encryption with the AWS SDK for Java and Amazon S3.