

本文為英文版的機器翻譯版本，如內容有任何歧義或不一致之處，概以英文版為準。

# 使用 EMRFS 屬性來指定 Amazon S3 加密
<a name="emr-emrfs-encryption"></a>

**重要**  
從 Amazon EMR 發行版本 4.8.0 開始，您可以使用安全組態設定來更輕鬆地並透過更多選項套用加密設定。我們建議您使用安全組態。如需詳細資訊，請參閱[設定資料加密](https://docs.aws.amazon.com/emr/latest/ManagementGuide/emr-create-security-configuration.html#emr-security-configuration-encryption)。本節所述的主控台說明在 4.8.0 之前的發行版本提供。如果您使用 AWS CLI 在叢集組態和後續版本的安全組態中設定 Amazon S3 加密，則安全組態會覆寫叢集組態。

建立叢集時，您可以使用主控台或透過 或 EMR SDK 使用`emrfs-site`分類屬性，為 Amazon S3 中的 EMRFS 資料指定伺服器端加密 (SSE) AWS CLI 或用戶端加密 (CSE)。Amazon S3 SSE 和 CSE 互斥；您可以選擇其中之一，但無法同時選擇。

如需 AWS CLI 說明，請參閱下方適用於加密類型的適當區段。

**使用 指定 EMRFS 加密選項 AWS 管理主控台**

1. 導覽至新的 Amazon EMR 主控台，然後從側邊導覽選取**切換至舊主控台**。如需有關切換至舊主控台時預期情況的詳細資訊，請參閱[使用舊主控台](https://docs.aws.amazon.com/emr/latest/ManagementGuide/whats-new-in-console.html#console-opt-in)。

1. 選擇 **Create cluster (建立叢集)**，然後選擇 **Go to advanced options (前往進階選項)**。

1. 選擇 4.7.2 或之前的 **Release (版本)**。

1. 選擇適用於應用程式的 **Software and Steps (軟體和步驟)** 的其他選項，然後選擇 **Next (下一步)**。

1. 選擇在 **Hardware (硬體)** 和 **General Cluster Settings (一般叢集設定)** 窗格中適用於您的應用程式的設定。

1. 在 **Security (安全)** 窗格上，在 **Authentication and encryption (身分驗證和加密)** 下，選取要使用的 **S3 Encryption (with EMRFS) (S3 加密 (搭配 EMRFS))**。
**注意**  
**使用 KMS 金鑰管理的 S3 伺服器端加密** (SSE-KMS) 在使用 Amazon EMR 發行版本 4.4 或更早版本時無法使用。
   + 如果您選擇使用 **AWS 金鑰管理**的選項，請選擇 **AWS KMS 金鑰 ID**。如需詳細資訊，請參閱[使用 AWS KMS keys 進行 EMRFS 加密](#emr-emrfs-awskms)。
   + 如果您選擇 **S3 client-side encryption with custom materials provider (S3 用戶端加密搭配自訂資料供應商)**，請提供 **Class name (類別名稱)** 和 **JAR location (JAR 位置)**。如需詳細資訊，請參閱[Amazon S3 用戶端加密](emr-emrfs-encryption-cse.md)。

1. 選擇適用於應用程式的其他選項，然後選擇 **Create Cluster (建立叢集)**。

## 使用 AWS KMS keys 進行 EMRFS 加密
<a name="emr-emrfs-awskms"></a>

 AWS KMS 加密金鑰必須在與 Amazon EMR 叢集執行個體和與 EMRFS 搭配使用的 Amazon S3 儲存貯體相同的區域中建立。如果您指定的金鑰與用來設定叢集的帳戶位於不同的帳戶中，您必須使用其 ARN 指定金鑰。

Amazon EC2 執行個體設定檔的角色必須具有使用您指定的 KMS 金鑰的許可。Amazon EMR 中執行個體設定檔的預設角色為 `EMR_EC2_DefaultRole`。如果您對執行個體設定檔使用不同的角色，或向 Amazon S3 請求使用 EMRFS 的 IAM 角色，請確保每個角色都會視情況新增為金鑰使用者。這會授予角色使用 KMS 金鑰的許可。如需詳細資訊，請參閱《AWS Key Management Service 開發人員指南》**中的[使用金鑰政策](https://docs.aws.amazon.com/kms/latest/developerguide/key-policies.html#key-policy-default-allow-users)和[設定向 Amazon S3 請求使用 EMRFS 的 IAM 角色](https://docs.aws.amazon.com/emr/latest/ManagementGuide/emr-emrfs-iam-roles.html)。

您可以使用 AWS 管理主控台 將執行個體描述檔或 EC2 執行個體描述檔新增至指定 KMS 金鑰的金鑰使用者清單，或使用 AWS CLI 或 AWS SDK 連接適當的金鑰政策。

請記住，Amazon EMR 僅支援[對稱 KMS 金鑰](https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#symmetric-cmks)。您無法使用[非對稱 KMS 金鑰](https://docs.aws.amazon.com/kms/latest/developerguide/symmetric-asymmetric.html#asymmetric-cmks)來加密 Amazon EMR 叢集中的靜態資料。如需判斷 KMS 金鑰為對稱或非對稱的說明，請參閱[識別對稱和非對稱 KMS 金鑰](https://docs.aws.amazon.com/kms/latest/developerguide/find-symm-asymm.html)。

下面的程序描述如何使用 AWS 管理主控台新增預設 Amazon EMR 執行個體設定檔 `EMR_EC2_DefaultRole` 作為*金鑰使用者*。這裡假設您已建立 KMS 金鑰。若要建立新的 KMS 金鑰，請參閱《AWS Key Management Service 開發人員指南》**中的[建立金鑰](https://docs.aws.amazon.com/kms/latest/developerguide/create-keys.html)。

**將 Amazon EMR 的 EC2 執行個體設定檔新增至加密金鑰使用者的清單**

1. 登入 AWS 管理主控台 並開啟位於 https：//[https://console.aws.amazon.com/kms](https://console.aws.amazon.com/kms) 的 AWS Key Management Service (AWS KMS) 主控台。

1. 若要變更 AWS 區域，請使用頁面右上角的區域選擇器。

1. 選取要修改的 KMS 金鑰別名。

1. 在 **Key Users (金鑰使用者)** 下的金鑰詳細資訊頁面上，選擇 **Add (新增)**。

1. 在 **Add key users (新增金鑰使用者)** 對話方塊中，選取適當的角色。預設角色的名稱為 `EMR_EC2_DefaultRole`。

1. 選擇**新增**。

## Amazon S3 伺服器端加密
<a name="emr-emrfs-encryption-sse"></a>

所有 Amazon S3 儲存貯體都已預設設定加密，且所有上傳至 S3 儲存貯體的新物件都會在靜態時自動加密，Amazon S3 會在將資料寫入磁碟時加密物件層級的資料，並在存取資料時解密資料。如需有關 SSE 的詳細資訊，請參閱《Amazon Simple Storage Service 使用者指南》**中的[使用伺服器端加密保護資料](https://docs.aws.amazon.com/AmazonS3/latest/userguide/serv-side-encryption.html)。

當您在 Amazon EMR 中指定 SSE 時，您可以在兩種不同的金鑰管理系統中選擇：
+ **SSE-S3** – Amazon S3 為您管理密鑰。
+ **SSE-KMS** – 您可以使用 AWS KMS key 來設定適用於 Amazon EMR 的政策。如需 Amazon EMR 金鑰需求的詳細資訊，請參閱[使用 AWS KMS keys 進行加密](https://docs.aws.amazon.com/emr/latest/ManagementGuide/emr-encryption-enable.html#emr-awskms-keys)。

使用客戶提供的金鑰的 SSE (SSE-C) 不適用於 Amazon EMR。

**使用 建立已啟用 SSE-S3 的叢集 AWS CLI**
+ 鍵入以下命令：

  ```
  aws emr create-cluster --release-label emr-4.7.2 or earlier \
  --instance-count 3 --instance-type m5.xlarge --emrfs Encryption=ServerSide
  ```

您也可以透過在 `emrfs-site` 屬性中將 fs.s3.enableServerSideEncryption 屬性設定為 true 來啟用 SSE-S3。請參閱以下 SSE-KMS 的範例並省略金鑰 ID 屬性。

**使用 建立已啟用 SSE-KMS 的叢集 AWS CLI**
**注意**  
SSE-KMS 僅能在 Amazon EMR 發行版本 4.5.0 及更新版本中使用。
+ 輸入下列 AWS CLI 命令以使用 SSE-KMS 建立叢集，其中 *keyID* 為 AWS KMS key，例如 *a4567b8-9900-12ab-1234-123a45678901*：

  ```
  aws emr create-cluster --release-label emr-4.7.2 or earlier --instance-count 3 \
  --instance-type m5.xlarge --use-default-roles \
  --emrfs Encryption=ServerSide,Args=[fs.s3.serverSideEncryption.kms.keyId=keyId]
  ```

  **--或--**

  使用 `emrfs-site`分類輸入下列 AWS CLI 命令，並提供包含內容的組態 JSON 檔案，如以下`myConfig.json`範例所示：

  ```
  aws emr create-cluster --release-label emr-4.7.2 or earlier --instance-count 3 --instance-type m5.xlarge --applications Name=Hadoop --configurations file://myConfig.json --use-default-roles
  ```

  範例內容 **myConfig.json**：

  ```
  [
    {
      "Classification":"emrfs-site",
      "Properties": {
         "fs.s3.enableServerSideEncryption": "true",
         "fs.s3.serverSideEncryption.kms.keyId":"a4567b8-9900-12ab-1234-123a45678901"
      }
    }
  ]
  ```

### SSE-S3 和 SSE-KMS 的組態屬性
<a name="emr-emrfs-encryption-site-sse-properties"></a>

可使用 `emrfs-site` 組態分類以設定這些屬性。SSE-KMS 僅能在 Amazon EMR 發行版本 4.5.0 及更新版本中使用。


| 屬性  | 預設值 | Description  | 
| --- | --- | --- | 
| fs.s3.enableServerSideEncryption | false |  設定為 **true** 時，會使用伺服器端加密對儲存在 Amazon S3 中的物件加密。如果沒有指定金鑰，則會使用 SSE-S3。  | 
| fs.s3.serverSideEncryption.kms.keyId | n/a |  指定 AWS KMS 金鑰 ID 或 ARN。如果已指定金鑰，則會使用 SSE-KMS。  | 

# Amazon S3 用戶端加密
<a name="emr-emrfs-encryption-cse"></a>

使用 Amazon S3 用戶端加密，Amazon S3 加密及解密會在您 EMR 叢集上的 EMRFS 用戶端中進行。物件在上傳至 Amazon S3 之前會先加密，並在下載後解密。您指定的提供者會提供用戶端使用的加密金鑰。用戶端可以使用 AWS KMS (CSE-KMS) 提供的金鑰或提供用戶端根金鑰 (CSE-C) 的自訂 Java 類別。CSE-KMS 和 CSE-C 之間的加密細節略有不同，具體取決於指定的提供者和要解密或加密之物件的中繼資料。如需有關這些差異的詳細資訊，請參閱《Amazon Simple Storage Service 使用者指南》**中的[使用用戶端加密保護資料](https://docs.aws.amazon.com/AmazonS3/latest/userguide/UsingClientSideEncryption.html)。

**注意**  
Amazon S3 CSE 只能確保與 Amazon S3 交換的 EMRFS 資料經過加密；而不會加密叢集執行個體磁碟區上的所有資料。此外，由於 Hue 不使用 EMRFS，因此 Hue S3 檔案瀏覽器寫入到 Amazon S3 的物件不會被加密。

**使用 為 Amazon S3 中的 EMRFS 資料指定 CSE-KMS AWS CLI**
+ 鍵入下列命令，並將 *MyKMSKeyID* 取代為要使用的 KMS 金鑰的金鑰 ID 或 ARN：

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

## 建立自訂金鑰提供者
<a name="emr-emrfs-create-cse-key"></a>

根據您在建立自訂金鑰提供者時使用的加密類型，應用程式也必須實作不同的 EncryptionMaterialsProvider 介面。適用於 Java 的 AWS 開發套件 1.11.0 版及更新版本提供這兩個界面。
+ 若要實作 Amazon S3 加密，請使用 [ com.amazonaws.services.s3.model.EncryptionMaterialsProvider 介面](https://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/services/s3/model/EncryptionMaterialsProvider.html)。
+ 若要實作本機磁碟加密，請使用 [ com.amazonaws.services.elasticmapreduce.spi.security.EncryptionMaterialsProvider 介面](https://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/services/elasticmapreduce/spi/security/EncryptionMaterialsProvider.html)。

您可以使用任何策略來為實作提供加密資料。例如，您可以選擇提供靜態加密資料，或與更複雜的金鑰管理系統整合。

如果您使用 Amazon S3 加密，則必須將加密演算法 **AES/GCM/NoPadding** 用於自訂加密資料。

如果您使用的是本機磁碟加密，則用於自訂加密資料的加密演算法會因 EMR 版本而有所不同。對於 Amazon EMR 7.0.0 及更低版本，您必須使用 **AES/GCM/NoPadding**。對於 Amazon EMR 7.1.0 及更高版本，您必須使用 **AES**。

EncryptionMaterialsProvider 類別會透過加密內容取得加密資料。Amazon EMR 會在執行期填入加密內容資訊，以協助呼叫者判斷要傳回的正確加密資料。

**Example 範例：透過 EMRFS 使用自訂金鑰提供者進行 Amazon S3 加密**  
當 Amazon EMR 從 EncryptionMaterialsProvider 類別擷取加密資料以執行加密時，EMRFS 會選擇性地將 materialsDescription 引數填入兩個欄位：物件的 Amazon S3 URI 和叢集的 JobFlowId (可供 EncryptionMaterialsProvider 類別使用以選擇性地傳回加密資料)。  
例如，提供者可能會針對不同的 Amazon S3 URI 字首傳回不同的金鑰。這是傳回的加密資料的描述，最終會與 Amazon S3 物件一起儲存，而不是 EMRFS 產生並傳遞給提供者的 materialsDescription 值。解密 Amazon S3 物件時，加密資料描述會傳遞至 EncryptionMaterialsProvider 類別，以便再次選擇性地傳回相符的金鑰以解密物件。  
下面提供了 EncryptionMaterialsProvider 參考實作。另一個自訂提供者 [EMRFSRSAEncryptionMaterialsProvider](https://github.com/awslabs/emr-sample-apps/tree/master/emrfs-plugins/EMRFSRSAEncryptionMaterialsProvider) 可從 GitHub 取得。  

```
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
<a name="emr-emrfs-encryption-cse-custom-cli"></a>

若要使用 AWS CLI，請將 `Encryption`、`ProviderType`、`CustomProviderClass` 和 `CustomProviderLocation` 引數傳遞給 `emrfs` 選項。

```
aws emr create-cluster --instance-type m5.xlarge --release-label emr-4.7.2 or earlier --emrfs Encryption=ClientSide,ProviderType=Custom,CustomProviderLocation=s3://amzn-s3-demo-bucket/myfolder/provider.jar,CustomProviderClass=classname
```

將 `Encryption` 設定為 `ClientSide` 會啟用用戶端加密，`CustomProviderClass` 是 `EncryptionMaterialsProvider` 物件的名稱，而 `CustomProviderLocation` 是本機 或 Amazon S3 位置，Amazon EMR 會從其中將 `CustomProviderClass` 複製到叢集中每個節點並將其置於 classpath。

## 使用 SDK 指定自訂資料提供者
<a name="emr-emrfs-encryption-cse-custom-sdk"></a>

若要使用 SDK,，您可以設定屬性 `fs.s3.cse.encryptionMaterialsProvider.uri` 以將您儲存在 Amazon S3 中的自訂 `EncryptionMaterialsProvider` 類別下載至叢集中的每個節點。您在 `emrfs-site.xml` 檔案 (已啟用 CSE) 中進行此設定以及自訂的供應商的適當位置。

例如， 適用於 Java 的 AWS SDK 在使用 RunJobFlowRequest 的 中，您的程式碼可能如下所示：

```
<snip>
		Map<String,String> emrfsProperties = new HashMap<String,String>();
	    	emrfsProperties.put("fs.s3.cse.encryptionMaterialsProvider.uri","s3://amzn-s3-demo-bucket/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-7.12.0")
			.withApplications(myApp)
			.withConfigurations(myEmrfsConfig)
			.withServiceRole("EMR_DefaultRole_V2")
			.withJobFlowRole("EMR_EC2_DefaultRole")
			.withLogUri("s3://myLogUri/")
			.withInstances(new JobFlowInstancesConfig()
				.withEc2KeyName("myEc2Key")
				.withInstanceCount(2)
				.withKeepJobFlowAliveWhenNoSteps(true)
				.withMasterInstanceType("m5.xlarge")
				.withSlaveInstanceType("m5.xlarge")
			);						
					
		RunJobFlowResult result = emr.runJobFlow(request);
</snip>
```

## 具有參數的自訂 EncryptionMaterialsProvider
<a name="emr-emrfs-encryption-custommaterials"></a>

您可能需要直接將引數傳遞給供應商。若要這樣做，您可以使用 `emrfs-site` 組態分類與定義為屬性的自訂引數。其中一個範例組態如下所示，其會儲存為檔案 (`myConfig.json`)：

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

使用來自 的 `create-cluster`命令 AWS CLI，您可以使用 `--configurations`選項來指定 檔案，如下所示：

```
aws emr create-cluster --release-label emr-7.12.0 --instance-type m5.xlarge --instance-count 2 --configurations file://myConfig.json --emrfs Encryption=ClientSide,CustomProviderLocation=s3://amzn-s3-demo-bucket/myfolder/myprovider.jar,CustomProviderClass=classname
```

## 設定 EMRFS S3EC V2 支援
<a name="emr-emrfs-encryption-cse-s3v2"></a>

S3 Java SDK 版本 (1.11.837 及更新版本) 支援具有各種安全增強功能的加密用戶端第 2 版 (S3EC V2)。如需詳細資訊，請參閱 S3 部落格文章 [Amazon S3 加密用戶端的更新](https://aws.amazon.com/blogs/developer/updates-to-the-amazon-s3-encryption-client/)。此外，請參閱[《 開發人員指南》中的 Amazon S3 加密用戶端遷移](https://docs.aws.amazon.com/sdk-for-java/v1/developer-guide/s3-encryption-migration.html)。 適用於 Java 的 AWS SDK 

SDK 中仍提供加密用戶端 V1 以實現回溯相容性。依預設，如果已啟用 CSE，EMRFS 將使用 S3EC V1 來加密和解密 S3 物件。

在發行版本早於 emr-5.31.0 (emr-5.30.1 及更早版本、emr-6.1.0 及更早版本) 的 EMR 叢集上，EMRFS 無法解密使用 S3EC V2 加密的 S3 物件。

**Example 將 EMRFS 設定為使用 S3EC V2**  
若要將 EMRFS 設定為使用 S3EC V2，請新增下列組態：  

```
{
  "Classification": "emrfs-site",
  "Properties": {
    "fs.s3.cse.encryptionV2.enabled": "true"
  }
}
```

## Amazon S3 用戶端加密的 `emrfs-site.xml` 屬性
<a name="emr-emrfs-cse-config"></a>


| 屬性  | 預設值 | Description  | 
| --- | --- | --- | 
| fs.s3.cse.enabled | false |  設定為 **true** 時，會使用用戶端加密對儲存在 Amazon S3 中的 EMRFS 物件加密。  | 
| fs.s3.cse.encryptionV2.enabled | false |  設定為 `true` 時，EMRFS 會使用 S3 加密用戶端第 2 版來加密和解密 S3 上的物件。適用於 EMR 5.31.0 版及更新版本。  | 
| fs.s3.cse.encryptionMaterialsProvider.uri | N/A | 當使用自訂加密資料。具有 EncryptionMaterialsProvider 的 JAR 所在的 Amazon S3 URI。當您提供此 URI 時，Amazon EMR 會自動將 JAR 下載至叢集中的所有節點。 | 
| fs.s3.cse.encryptionMaterialsProvider | N/A |  與用戶端加密搭配使用的 `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 | N/A |  使用 CSE-KMS 時進行套用。用於加密的 KMS 金鑰的 KeyId、ARN 或別名的值。  | 
| fs.s3.cse.cryptoStorageMode | ObjectMetadata  |  Amazon S3 儲存模式。預設情況下，加密資訊的描述會儲存在物件中繼資料。您也可以將說明存放在指令檔案。有效值為 ObjectMetadata 和 InstructionFile。如需詳細資訊，請參閱[使用 適用於 Java 的 AWS SDK 和 Amazon S3 進行用戶端資料加密](https://aws.amazon.com/articles/client-side-data-encryption-with-the-aws-sdk-for-java-and-amazon-s3/)。  | 