

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

# Amazon S3 加密用戶端遷移 (V1 至 V2)
<a name="s3-encryption-migration-v1-v2"></a>

**注意**  
如果您使用的是 S3 加密用戶端的 V2，並且想要遷移至 V3，請參閱 [Amazon S3 加密用戶端遷移 (V2 到 V3)](s3-encryption-migration-v2-v3.md)。

本主題說明如何將應用程式從 Amazon Simple Storage Service (Amazon S3) 加密用戶端的第 1 版 (V1) 遷移到第 2 版 (V2)，並確保在整個遷移過程中的應用程式可用性。

## 遷移概觀
<a name="migration-overview-v1-v2"></a>

此遷移分為兩個階段：

1. **更新現有用戶端以讀取新格式。**首先，將適用於 Ruby 的 AWS SDK 更新版本部署到您的應用程式。這將允許現有的 V1 加密用戶端解密新 V2 用戶端寫入的物件。如果您的應用程式使用多個 AWS SDKs，您必須分別升級每個 SDK。

2. **將加密和解密用戶端遷移至 V2。**一旦所有 V1 加密用戶端都可以讀取新的格式，您就可以將現有的加密和解密用戶端遷移到各自的 V2 版本。

## 更新現有用戶端以讀取新格式
<a name="update-existing-clients-to-read-new-formats-v1-v2"></a>

V2 加密用戶端使用舊版用戶端不支援的加密演算法。遷移的第一步是將 V1 解密用戶端更新為最新的 SDK 版本。完成此步驟後，應用程式的 V1 用戶端將能夠解密 V2 加密用戶端加密的物件。如需適用於 Ruby 的 AWS SDK 每個主要版本的詳細資訊，請參閱下列內容。

### 更新適用於 Ruby 的 AWS SDK 第 3 版
<a name="update-aws-sdk-for-ruby-version-3-v1-v2"></a>

第 3 版是適用於 Ruby 的 AWS SDK 最新版本。若要完成此遷移，您需要使用 1.76.0 版或更新版本的 `aws-sdk-s3` Gem 套件。

 **從命令列安裝** 

對於安裝 `aws-sdk-s3` Gem 的專案，請使用版本選項來驗證已安裝最低版本 1.76.0。

```
gem install aws-sdk-s3 -v '>= 1.76.0'
```

 **使用 Gemfile** 

對於使用 Gemfile 管理相依性的專案，請將 `aws-sdk-s3` Gem 的最低版本設定為 1.76.0。例如：

```
gem 'aws-sdk-s3', '>= 1.76.0'
```

1. 修改 Gemfile。

1. 執行 `bundle update aws-sdk-s3`。若要驗證您的版本，請執行 `bundle info aws-sdk-s3`。

### 適用於 Ruby 的升級 AWS SDK 第 2 版
<a name="upgdate-aws-sdk-for-ruby-version-2-v1-v2"></a>

適用於 Ruby 的 AWS SDK 第 2 版將於 2021 年 11 月 21 日進入[維護模式](https://aws.amazon.com/blogs/developer/deprecation-schedule-for-aws-sdk-for-ruby-v2/)。若要完成此遷移，您需要使用 2.11.562 版或更新版本的 aws-sdk Gem 套件。

 **從命令列安裝** 

對於安裝 `aws-sdk` Gem 的專案，請從命令列使用版本選項來驗證已安裝最低版本 2.11.562。

```
gem install aws-sdk -v '>= 2.11.562'
```

 **使用 Gemfile** 

對於使用 Gemfile 管理相依性的專案，請將 `aws-sdk` Gem 的最低版本設定為 2.11.562。例如：

```
gem 'aws-sdk', '>= 2.11.562'
```

1. 修改 Gemfile。如果您有 Gemfile.lock 檔案，請刪除或更新它。

1. 執行 `bundle update aws-sdk`。若要驗證您的版本，請執行 `bundle info aws-sdk`。

## 將加密和解密用戶端遷移至 V2
<a name="migrate-encryption-and-decryption-clients-to-v2-v1-v2"></a>

將用戶端更新為讀取新的加密格式後，您可以將應用程式更新為 V2 加密和解密用戶端。下列步驟說明如何成功將程式碼從 V1 遷移至 V2。

在更新您的程式碼以使用 V2 加密用戶端之前，請確定您已遵循上述步驟，並使用 `aws-sdk-s3` Gem 2.11.562 版或更新版本。

**注意**  
使用 AES-GCM 解密時，請先將整個物件讀到結尾，再開始使用解密的資料。這是為了驗證物件在加密後尚未修改。

### 設定 V2 加密用戶端
<a name="configuring-v2-encryption-clients-v1-v2"></a>

*EncryptionV2：：Client* 需要額外的組態。如需詳細的組態資訊，請參閱 [EncryptionV2：：Client 文件](https://docs.aws.amazon.com/sdk-for-ruby/v3/api/Aws/S3/EncryptionV2/Client.html#initialize-instance_method)或本主題稍後提供的範例。

1. **金鑰包裝方法和內容加密演算法必須在用戶端建構時指定。**建立新的 時`EncryptionV2::Client`，您需要提供 `key_wrap_schema`和 的值`content_encryption_schema`。

 `key_wrap_schema` - 如果您使用的是 AWS KMS，這必須設定為 `:kms_context`。如果您使用對稱 (AES) 金鑰，則必須將其設定為 `:aes_gcm`。如果您使用非對稱 (RSA) 金鑰，則必須將其設定為 `:rsa_oaep_sha1`。

 `content_encryption_schema` - 這必須設定為 *：aes\_gcm\_no\_padding*。

2. **必須在用戶端建構時指定 security\_profile。**建立新的 時`EncryptionV2::Client`，您需要提供 的值`security_profile`。*security\_profile* 參數決定支援讀取使用舊版 V1 寫入的物件`Encryption::Client`。有兩個值：*：v2* 和 *：v2\_and\_legacy*。若要支援遷移，請將 `security_profile`設定為 *：v2\_and\_legacy*。僅將 *：v2* 用於新的應用程式開發。

3. **AWS KMS key ID 預設會強制執行。**在 V1 中，`kms_key_id`用於建立用戶端的 `Encryption::Client`並未提供給 AWS KMS `Decrypt call`。 AWS KMS 可以從中繼資料取得此資訊，並將其新增至對稱加密文字 Blob。在 V2 中，E`ncryptionV2：：Client` 會將 *kms\_key\_id* 傳遞給 AWS KMS Decrypt 呼叫，如果呼叫不符合用來加密物件的金鑰，則呼叫會失敗。如果您的程式碼先前倚賴未設定特定 `kms_key_id`，請在建立用戶端`kms_key_id: :kms_allow_decrypt_with_any_cmk`時設定 ，或在`get_object`呼叫`kms_allow_decrypt_with_any_cmk: true`時設定 。

### 範例：使用對稱 (AES) 金鑰
<a name="example-using-a-symmetric-aes-key-v1-v2"></a>

 **預遷移** 

```
client = Aws::S3::Encryption::Client.new(encryption_key: aes_key)
client.put_object(bucket: bucket, key: key, body: secret_data)
resp = client.get_object(bucket: bucket, key: key)
```

 **遷移後** 

```
client = Aws::S3::EncryptionV2::Client.new(
  encryption_key: rsa_key,
  key_wrap_schema: :rsa_oaep_sha1, # the key_wrap_schema must be rsa_oaep_sha1 for asymmetric keys
  content_encryption_schema: :aes_gcm_no_padding,
  security_profile: :v2_and_legacy # to allow reading/decrypting objects encrypted by the V1 encryption client
 )
client.put_object(bucket: bucket, key: key, body: secret_data)  # No changes
resp = client.get_object(bucket: bucket, key: key) # No changes
```

### 範例： AWS KMS 搭配 kms\_key\_id 使用
<a name="example-using-aws-kms-with-kms-key-id-v1-v2"></a>

 **預遷移** 

```
client = Aws::S3::Encryption::Client.new(kms_key_id: kms_key_id)
client.put_object(bucket: bucket, key: key, body: secret_data)
resp = client.get_object(bucket: bucket, key: key)
```

 **遷移後** 

```
client = Aws::S3::EncryptionV2::Client.new(
  kms_key_id: kms_key_id,
  key_wrap_schema: :kms_context, # the key_wrap_schema must be kms_context for KMS keys
  content_encryption_schema: :aes_gcm_no_padding,
  security_profile: :v2_and_legacy # to allow reading/decrypting objects encrypted by the V1 encryption client
)
client.put_object(bucket: bucket, key: key, body: secret_data)  # No changes
resp = client.get_object(bucket: bucket, key: key) # No change
```

### 範例：使用 AWS KMS 而不使用 kms\_key\_id
<a name="example-using-aws-kms-without-kms-key-id-v1-v2"></a>

 **預遷移** 

```
client = Aws::S3::Encryption::Client.new(kms_key_id: kms_key_id)
client.put_object(bucket: bucket, key: key, body: secret_data)
resp = client.get_object(bucket: bucket, key: key)
```

 **遷移後** 

```
client = Aws::S3::EncryptionV2::Client.new(
  kms_key_id: kms_key_id,
  key_wrap_schema: :kms_context, # the key_wrap_schema must be kms_context for KMS keys
  content_encryption_schema: :aes_gcm_no_padding,
  security_profile: :v2_and_legacy # to allow reading/decrypting objects encrypted by the V1 encryption client
)
client.put_object(bucket: bucket, key: key, body: secret_data)  # No changes
resp = client.get_object(bucket: bucket, key: key, kms_allow_decrypt_with_any_cmk: true) # To allow decrypting with any cmk
```

 **遷移後替代方案** 

如果您只使用 S2 加密用戶端讀取和解密 （絕不寫入和加密） 物件，請使用此程式碼。

```
client = Aws::S3::EncryptionV2::Client.new(
  kms_key_id: :kms_allow_decrypt_with_any_cmk, # set kms_key_id to allow all get_object requests to use any cmk
  key_wrap_schema: :kms_context, # the key_wrap_schema must be kms_context for KMS keys
  content_encryption_schema: :aes_gcm_no_padding,
  security_profile: :v2_and_legacy # to allow reading/decrypting objects encrypted by the V1 encryption client
)
resp = client.get_object(bucket: bucket, key: key) # No change
```