

翻訳は機械翻訳により提供されています。提供された翻訳内容と英語版の間で齟齬、不一致または矛盾がある場合、英語版が優先します。

# データモデルの変更
<a name="data-model"></a>

**注記**  
クライアント側の暗号化ライブラリの名前が [AWS Database Encryption SDK](DDBEC-rename.md) に変更されました。次のトピックには、DynamoDB Encryption Client for Java のバージョン 1.x～2.x および DynamoDB Encryption Client for Python のバージョン 1.x～3.x に関する情報が記載されています。詳細については、「[AWS Database Encryption SDK for DynamoDB バージョンのサポート](legacy-dynamodb-encryption-client.md#legacy-support)」を参照してください。

項目を暗号化または復号するたびに、暗号化して署名する属性、署名する (ただし、暗号化はしない) 属性、および無視する属性を DynamoDB 暗号化クライアントに伝達する[属性アクション](DDBEC-legacy-concepts.md#legacy-attribute-actions)を指定する必要があります。属性アクションは、暗号化された項目に保存されないため、DynamoDB 暗号化クライアントは属性アクションを自動的に処理しません。

**重要**  
DynamoDB Encryption Client は、既存の暗号化されていない DynamoDB テーブルデータの暗号化をサポートしていません。

データモデルを変更するたびに、つまり、テーブル項目から属性を追加または削除すると、エラーが発生する危険性があります。指定した属性アクションが、項目のすべての属性で構成されていない場合、その項目は、意図した方法で暗号化および署名されない場合があります。さらに重要な点として、項目の復号時に指定する属性アクションが、項目の暗号化時に指定した属性アクションと異なる場合は、署名検証が失敗する場合があります。

たとえば、項目の暗号化に使用する属性アクションで、`test` 属性に署名するよう指示した場合、その項目の署名には `test` 属性が含まれます。項目の復号に使用する属性アクションが、`test` 属性で構成されていない場合、クライアントは `test` 属性を含まない署名の検証を試みるため、検証は失敗します。

これは、DynamoDB 暗号化クライアントがすべてのアプリケーションの項目に対して同じ署名を計算する必要があるため、複数のアプリケーションが同じ DynamoDB 項目の読み取りおよび書き込みを行う場合に特に問題になります。また、属性アクションの変更がすべてのホストに反映される必要があるため、分散アプリケーションでも問題になります。DynamoDB テーブルが 1 つのプロセスで 1 つのホストによってアクセスされる場合でも、ベストプラクティスプロセスを確立すると、プロジェクトが複雑になった場合にエラーを防ぐことができます。

テーブル項目を読み取ることができない署名検証エラーを回避するには、次のガイダンスを使用します。
+ [属性の追加](#add-attribute) — 新しい属性によって属性アクションが変更される場合は、項目に新しい属性を含める前に属性アクションの変更を完全にデプロイします。
+ [属性の削除](#remove-attribute) - 項目で属性の使用を中止する場合は、属性アクションを変更しないでください。
+ アクションの変更 - 属性アクション設定を使用してテーブル項目を暗号化した後は、テーブル内のすべての項目を再暗号化しなければ、デフォルトのアクションまたは既存の属性のアクションを安全に変更することはできません。

署名検証エラーは解決が非常に困難な場合があるため、最善の方法は、それらのエラーを回避することです。

**Topics**
+ [属性の追加](#add-attribute)
+ [属性の削除](#remove-attribute)

## 属性の追加
<a name="add-attribute"></a>

テーブル項目に新しい属性を追加する場合、属性アクションの変更が必要になることがあります。署名検証エラーを回避するために、この変更を 2 ステージのプロセスで実装することをお勧めします。第 2 ステージを開始する前に、第 1 ステージが完了していることを確認します。

1. テーブルの読み取りまたは書き込みを行うすべてのアプリケーションで属性アクションを変更します。これらの変更をデプロイして、更新がすべての送信先ホストに反映されていることを確認します。

1. テーブル項目の新しい属性に値を書き込みます。

この 2 ステージのアプローチでは、すべてのアプリケーションおよびホストに同じ属性アクションが設定され、新しい属性が見つかる前に同じ署名が計算されます。これは、属性のアクションが*何もしない* (暗号化または署名しない) 場合でも重要です。その理由は、一部の暗号化では暗号化と署名がデフォルトであるためです。

次の例は、このプロセスの第 1 ステージのコードを示しています。新しい項目属性 `link` が追加されます。これには、別のテーブル項目へのリンクが保存されます。このリンクはプレーンテキストのままにする必要があるため、この例では署名のみアクションを割り当てます。この変更を完全にデプロイし、すべてのアプリケーションおよびホストに新しい属性アクションがあることを確認したら、テーブル項目で `link` 属性の使用を開始します。

------
#### [ Java DynamoDB Mapper ]

`DynamoDB Mapper` と `AttributeEncryptor` を使用すると、デフォルトでは、プライマリキーを除く属性がすべて暗号化されます。これらの属性は署名されますが、暗号化はされません。署名のみアクションを指定するには、`@DoNotEncrypt` 注釈を使用します。

この例では、新しい `link` 属性に `@DoNotEncrypt` 注釈を使用します。

```
@DynamoDBTable(tableName = "ExampleTable")
public static final class DataPoJo {
  private String partitionAttribute;
  private int sortAttribute;
  private String link;

  @DynamoDBHashKey(attributeName = "partition_attribute")
  public String getPartitionAttribute() {
    return partitionAttribute;
  }
    
  public void setPartitionAttribute(String partitionAttribute) {
    this.partitionAttribute = partitionAttribute;
  }

  @DynamoDBRangeKey(attributeName = "sort_attribute")
  public int getSortAttribute() {
    return sortAttribute;
  }

  public void setSortAttribute(int sortAttribute) {
    this.sortAttribute = sortAttribute;
  }

  @DynamoDBAttribute(attributeName = "link")
  @DoNotEncrypt
  public String getLink() {
    return link;
  }

  public void setLink(String link) {
    this.link = link;
  }

  @Override
  public String toString() {
    return "DataPoJo [partitionAttribute=" + partitionAttribute + ",
        sortAttribute=" + sortAttribute + ",
        link=" + link + "]";
  }
}
```

------
#### [ Java DynamoDB encryptor ]

 下位レベルの DynamoDB エンクリプタでは、属性ごとにアクションを設定する必要があります。この例では、switch 文を使用します。デフォルトは `encryptAndSign` で、パーティションキー、ソートキー、および新しい `link` 属性に例外が指定されています。この例では、リンク属性コードが使用前に完全にデプロイされていない場合、リンク属性の暗号化および署名を行うアプリケーションや、リンク属性の署名のみを行うアプリケーションがあります。

```
for (final String attributeName : record.keySet()) {
    switch (attributeName) {
        case partitionKeyName:
            // fall through to the next case
        case sortKeyName:
            // partition and sort keys must be signed, but not encrypted
            actions.put(attributeName, signOnly);
            break;
        case "link":
            // only signed
            actions.put(attributeName, signOnly);
            break;
        default:
            // Encrypt and sign all other attributes
            actions.put(attributeName, encryptAndSign);
            break;
    }
}
```

------
#### [ Python ]

Python 用の DynamoDB 暗号化クライアントでは、すべての属性にデフォルトのアクションを指定してから、例外を指定できます。

Python [クライアントのヘルパークラス](python-using.md#python-helpers)を使用している場合は、プライマリキー属性の属性アクションを指定する必要はありません。クライアントのヘルパークラスを使用して、プライマリキーを暗号化することはできません。ただし、クライアントのヘルパークラスを使用していない場合は、パーティションキーとソートキーに SIGN\$1ONLY アクションを設定する必要があります。パーティションキーまたはソートキーを誤って暗号化した場合、完全なテーブルスキャンを行わないとデータを復元できません。

この例では、`SIGN_ONLY` アクションを取得する新しい `link` 属性の例外を指定します。

```
actions = AttributeActions(
    default_action=CryptoAction.ENCRYPT_AND_SIGN,
    attribute_actions={
      'example': CryptoAction.DO_NOTHING,  
      'link': CryptoAction.SIGN_ONLY
    }
)
```

------

## 属性の削除
<a name="remove-attribute"></a>

DynamoDB 暗号化クライアントで暗号化された項目で属性が不要になった場合は、その属性の使用を停止できます。ただし、その属性のアクションを削除または変更しないでください。その削除または変更を行ってから、その属性を持つ項目が見つかった場合、その項目に対して計算された署名は元の署名と一致せず、署名の検証は失敗します。

コードから属性のすべてのトレースを削除したいと思うかもしれませんが、項目を削除するのではなく、項目が使用されなくなったというコメントを追加してください。完全なテーブルスキャンを実行して属性のすべてのインスタンスを削除しても、その属性を持つ暗号化された項目は、設定のどこかでキャッシュされるか、または処理中になる可能性があります。