設定資 AWS 料庫加密 SDK - AWS 資料庫加密 SDK

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

設定資 AWS 料庫加密 SDK

我們的用戶端加密程式庫已重新命名為 AWS 資料庫加密 SDK。本開發人員指南仍提供 DynamoDB 加密用戶端的相關資訊。

數 AWS 據庫加密 SDK 被設計為易於使用。雖然 AWS 資料庫加密 SDK 有數個設定選項,但是預設值是經過仔細選擇,對於大多數應用程式來說是實用且安全的。不過,您可能需要調整組態以改善效能,或在設計中包含自訂功能。

選擇一種編程語言

適用於 DynamoDB 的 AWS 資料庫加密開發套件提供多種程式設計語言。語言實現被設計為完全可互操作,並提供相同的功能,儘管它們可能以不同的方式實現。一般而言,您會使用與應用程式相容的程式庫。

選擇包裝鍵

資料 AWS 庫加密 SDK 會產生唯一的對稱資料金鑰來加密每個欄位。您不需要設定、管理或使用資料金鑰。數 AWS 據庫加密 SDK 為您完成。

但是,您必須選取一或多個包裝金鑰來加密每個資料金鑰。資 AWS 料庫加密 SDK 支援 AWS Key Management Service(AWS KMS) 對稱式加密 KMS 金鑰和非對稱 RSA KMS 金鑰。它還支持 AES 對稱密鑰和您提供不同大小的 RSA 非對稱密鑰。您必須為包裝金鑰的安全性和耐久性負責,因此建議您在硬體安全性模組或金鑰基礎架構服務 (例如) 中使用加密金鑰 AWS KMS。

若要指定用於加密和解密的包裝金鑰,請使用金鑰環。根據您使用的金鑰圈類型,您可以指定一個包裝金鑰或多個相同或不同類型的包裝金鑰。如果您使用多個包裝金鑰來包裝資料金鑰,每個包裝金鑰都會加密相同資料金鑰的副本。加密的數據密鑰(每個包裝密鑰一個)存儲在與加密字段一起存儲的材料描述中。若要解密資料,資料 AWS 庫加密 SDK 必須先使用其中一個包裝金鑰來解密加密的資料金鑰。

我們建議盡可能使用其中一個 AWS KMS 鑰匙圈。資 AWS 料庫加密 SDK 提供AWS KMS 金鑰環AWS KMS 階層式金鑰圈,可減少呼叫的次數。 AWS KMS若要在金鑰環 AWS KMS key 中指定,請使用支援的 AWS KMS 金鑰識別碼。如果您使用 AWS KMS 階層式金鑰圈,則必須指定金鑰 ARN。如需金鑰的金鑰識別碼的詳細資訊,請參閱AWS Key Management Service 開發人員指南中的金鑰識別碼。 AWS KMS

  • 使用金 AWS KMS 鑰圈加密時,您可以為對稱加密 KMS 金鑰指定任何有效的金鑰識別碼 (金鑰 ARN、別名名稱、別名 ARN 或金鑰識別碼)。如果您使用非對稱 RSA KMS 金鑰,則必須指定金鑰 ARN。

    如果您在加密時為 KMS 金鑰指定別名或別名 ARN, AWS 資料庫加密 SDK 會儲存目前與該別名關聯的金鑰 ARN,但不會儲存別名。變更別名不會影響用於解密資料金鑰的 KMS 金鑰。

  • 根據預設,金 AWS KMS 鑰環會以嚴謹模式 (您指定特定 KMS 金鑰) 解密記錄。您必須使用金鑰 ARN 來識別以進行 AWS KMS keys 解密。

    當您使用金 AWS KMS 鑰圈加密時,資料 AWS 庫加密 SDK 會將材料描述 AWS KMS key 中的金鑰 ARN 與加密的資料金鑰一起儲存。在嚴謹模式下解密時, AWS 資料庫加密 SDK 會在嘗試使用環繞金鑰解密加密的資料金鑰之前,先驗證金鑰圈中是否出現相同的金鑰 ARN。如果您使用不同的金鑰識別碼, AWS 資料庫加密 SDK 將無法辨識或使用 AWS KMS key,即使識別碼參照相同的金鑰。

  • 探索模式下解密時,您不會指定任何包裝金鑰。首先,數 AWS 據庫加密 SDK 嘗試使用存儲在材料描述中的密鑰 ARN 解密記錄。如果沒有作用, AWS 資料庫加密 SDK 會 AWS KMS 要求使用加密記錄的 KMS 金鑰來解密記錄,無論誰擁有或擁有該 KMS 金鑰的存取權。

若要將原始 AES 金鑰原始 RSA key pair 指定為金鑰環中的環繞金鑰,您必須指定命名空間和名稱。解密時,您必須為每個原始包裝金鑰使用與加密時使用完全相同的命名空間和名稱。如果您使用不同的命名空間或名稱,即使金鑰材料相同,資料 AWS 庫加密 SDK 也不會辨識或使用包裝金鑰。

建立探索篩選器

解密使用 KMS 金鑰加密的資料時,最佳做法是在嚴謹模式下進行解密,也就是說,將使用的包裝金鑰限制為只有您指定的金鑰。不過,如有必要,您也可以在探索模式中解密,而您不需要指定任何包裝金鑰。在此模式中, AWS KMS 無論誰擁有或擁有該 KMS 金鑰的存取權,都可以使用加密的 KMS 金鑰來解密加密的資料金鑰。

如果您必須在探索模式中解密,建議您一律使用探索篩選器,這會限制可用於指定 AWS 帳戶 和分割區中的 KMS 金鑰。探索篩選器是選用的,但這是最佳作法。

使用下表決定探索篩選器的分割區值。

區域 分區
AWS 區域 aws
中國區域 aws-cn
AWS GovCloud (US) Regions aws-us-gov

下列範例顯示如何建立探索篩選器。在使用代碼之前,請將示例值替換為您的 AWS 帳戶 和分區的有效值。

Java
// Create the discovery filter DiscoveryFilter discoveryFilter = DiscoveryFilter.builder() .partition("aws") .accountIds(111122223333) .build();
C# / .NET
var discoveryFilter = new DiscoveryFilter { Partition = "aws", AccountIds = 111122223333 };

使用多租戶資料庫

透過資料 AWS 庫加密 SDK,您可以使用不同的加密材料隔離每個租用戶,藉此為具有共用結構描述的資料庫設定用戶端加密。考量多租戶資料庫時,請花一些時間檢閱您的安全性需求,以及多租戶可能對其造成的影響。例如,使用多租戶資料庫可能會影響您將資料 AWS 庫加密 SDK 與其他伺服器端加密解決方案結合的能力。

如果您有多個使用者在資料庫中執行加密作業,您可以使用其中一個金 AWS KMS 鑰環,為每位使用者提供不同的金鑰,以便在其加密編譯作業中使用。管理多租戶用戶端加密解決方案的資料金鑰可能很複雜。我們建議盡可能由租戶組織您的數據。如果租用戶是由主索引鍵值識別 (例如,Amazon DynamoDB 表格中的分區金鑰),則管理金鑰會更容易。

您可以使用AWS KMS 金鑰圈,透過不同的金 AWS KMS 鑰圈和隔離每個承租人。 AWS KMS keys根據每個租用戶 AWS KMS 撥打的通話量,您可能想要使用 AWS KMS 階層式金鑰圈來將您的通話降至 AWS KMS最低。AWS KMS 階層式金鑰圈是一種加密材料快取解決方案,可透過使用保存在 Amazon DynamoDB 表格中的 AWS KMS 受保護分支金鑰,然後在本機快取用於加密和解密作業的分支金鑰材料,以減少 AWS KMS 呼叫次數。您必須使用 AWS KMS 階層式金鑰環,在資料庫中實作可搜尋的加密

建立簽署的信標

AWS 資料庫加密 SDK 使用標準信標複合信標來提供可搜尋的加密解決方案,讓您搜尋加密的記錄,而無需解密查詢的整個資料庫。不過, AWS 資料庫加密 SDK 也支援已簽署的信標,這些信標可以完全從純文字簽署欄位進行設定。簽名信標是一種複合信標,可對和SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT字段進行複雜查詢編制索引SIGN_ONLY和執行。

例如,如果您有多租戶資料庫,您可能想要建立一個已簽署的信標,讓您查詢資料庫中的特定承租人金鑰加密的記錄。如需詳細資訊,請參閱 查詢多租戶資料庫中的信標

您必須使用 AWS KMS 階層式金鑰圈來建立已簽署的信標。

若要設定已簽署的信標,請提供下列值。

Java

複合信標配置

下列範例會在已簽署的信標 (Beacon) 組態中本機定義已簽署零件清單

List<CompoundBeacon> compoundBeaconList = new ArrayList<>(); CompoundBeacon exampleCompoundBeacon = CompoundBeacon.builder() .name("compoundBeaconName") .split(".") .signed(signedPartList) .constructors(constructorList) .build(); compoundBeaconList.add(exampleCompoundBeacon);

信標版本定義

下列範例會在信標 (Beacon) 版本中全域定義已簽署零件清單。如需有關定義信標版本的詳細資訊,請參閱使用信標

List<BeaconVersion> beaconVersions = new ArrayList<>(); beaconVersions.add( BeaconVersion.builder() .standardBeacons(standardBeaconList) .compoundBeacons(compoundBeaconList) .signedParts(signedPartList) .version(1) // MUST be 1 .keyStore(keyStore) .keySource(BeaconKeySource.builder() .single(SingleKeyStore.builder() .keyId(branchKeyId) .cacheTTL(6000) .build()) .build()) .build() );
C# / .NET

請參閱完整的程式碼範例BeaconConfig.cs

已簽署信標組態

下列範例會在已簽署的信標 (Beacon) 組態中本機定義已簽署零件清單

var compoundBeaconList = new List<CompoundBeacon>(); var exampleCompoundBeacon = new CompoundBeacon { Name = "compoundBeaconName", Split = ".", Signed = signedPartList, Constructors = constructorList }; compoundBeaconList.Add(exampleCompoundBeacon);

信標版本定義

下列範例會在信標 (Beacon) 版本中全域定義已簽署零件清單。如需有關定義信標版本的詳細資訊,請參閱使用信標

var beaconVersions = new List<BeaconVersion> { new BeaconVersion { StandardBeacons = standardBeaconList, CompoundBeacons = compoundBeaconList, SignedParts = signedPartsList, Version = 1, // MUST be 1 KeyStore = keyStore, KeySource = new BeaconKeySource { Single = new SingleKeyStore { KeyId = branchKeyId, CacheTTL = 6000 } } } };

您可以在本機或全域定義的清單中定義已簽署的零件。我們建議您盡可能在信標版本的全域清單中定義已簽署的零件。透過全域定義已簽署零件,您可以定義每個零件一次,然後在多個複合信標 (Beacon) 組態中重複使用零件 如果您只打算使用一次已簽署零件,則可以在已簽署的信標 (Beacon) 組態的本機清單中定義該零件。您可以在構造函數列表中引用本地和全局部分。

如果您全域定義已簽署零件清單,則必須提供建構函式零件清單,以識別已簽署信標 (Beacon) 組合信標 (Beacon) 組態中欄位的所有可能方式。

注意

若要全域定義已簽署零件清單,您必須使用 3.2 版或更新版本的 AWS 資料庫加密 SDK。在全域定義任何新零件之前,請先將新版本部署至所有讀取器。

您無法更新現有的信標組態以全域定義已簽署零件清單。

信標名稱

查詢信標時使用的名稱。

已簽署的信標名稱不能與未加密欄位的名稱相同。沒有兩個信標可以具有相同的信標名稱。

分割字元

用來分隔組成已簽署信標之零件的字元。

分割字元不能出現在已簽署信標所建構之任何欄位的純文字值中。

已簽署零件清單

識別已簽署信標中包含的已簽署欄位。

每個零件都必須包含名稱、來源和字首。來源是零件識別的SIGN_ONLYSIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT欄位。來源必須是欄位名稱或參照巢狀欄位值的索引。如果您的零件名稱識別來源,您可以省略來源, AWS 資料庫加密 SDK 會自動使用該名稱作為其來源。建議您盡可能將來源指定為零件名稱。前綴可以是任何字符串,但它必須是唯一的。簽署的信標中沒有兩個已簽署的零件可以具有相同的前綴。我們建議使用短值來區分零件與複合信標服務的其他零件。

我們建議您盡可能在全域定義已簽署的零件。如果您只打算在一個複合信標中使用已簽署零件,則可以考慮在本機定義已簽署零件。本機定義的零件不能具有與全域定義零件相同的字首或名稱。

Java
List<SignedPart> signedPartList = new ArrayList<>); SignedPart signedPartExample = SignedPart.builder() .name("signedFieldName") .prefix("S-") .build(); signedPartList.add(signedPartExample);
C# / .NET
var signedPartsList = new List<SignedPart> { new SignedPart { Name = "signedFieldName1", Prefix = "S-" }, new SignedPart { Name = "signedFieldName2", Prefix = "SF-" } };
構造函數列表(可選)

識別建構函式,這些建構函式會定義已簽署零件可由簽署的信標組裝的不同方式。

如果您未指定建構函式清單, AWS 資料庫加密 SDK 會使用下列預設建構函式組合已簽署的信標。

  • 所有已簽署零件的順序,均按其新增至已簽署零件清單的順序

  • 所有零件皆為必填

建構函式

每個構造函數都是構造函數部分的有序列表,它定義了有符號信標可以組裝的一種方式。構造函數部分按照它們被添加到列表中的順序連接在一起,每個部分由指定的拆分字符分隔。

每個構造函數部分命名一個帶符號的部分,並定義構造函數中該部分是必需的還是可選的。例如,如果您想要在、和上查詢已簽署的信標 Field1Field1.Field2,請將 and 標記Field3為可選Field1.Field2.Field3Field2並建立一個建構函式。

每個構造函數必須至少有一個必需的部分。我們建議在每個所需的構造函數中進行第一部分,以便您可以在查詢中使用BEGINS_WITH運算符。

如果記錄中存在其所有必需的部分,則構造函數成功。當您撰寫新記錄時,已簽署的信標會使用建構函式清單來判斷是否可以從提供的值組合信標。它嘗試按照構造函數添加到構造函數列表的順序組裝信標,並使用成功的第一個構造函數。如果沒有建構函式成功,信標就不會寫入記錄。

所有讀者和作者都應該指定相同的構造函數順序,以確保他們的查詢結果是正確的。

請使用下列程序來指定您自己的建構函式清單。

  1. 為每個已簽署的零件建立建構函式零件,以定義是否需要該部分。

    構造函數部分名稱必須是有符號字段的名稱。

    下面的例子演示瞭如何創建一個帶符號字段的構造部分。

    Java
    ConstructorPart field1ConstructorPart = ConstructorPart.builder() .name("Field1") .required(true) .build();
    C# / .NET
    var field1ConstructorPart = new ConstructorPart { Name = "Field1", Required = true };
  2. 為可以使用在步驟 1 中創建的構造函數部分組裝簽名信標的每種可能方式創建構函數。

    例如,如果你想查詢Field1.Field2.Field3Field4.Field2.Field3,那麼你必須創建兩個構造函數。 Field1並且都Field4可以是必需的,因為它們是在兩個單獨的構造函數中定義的。

    Java
    // Create a list for Field1.Field2.Field3 queries List<ConstructorPart> field123ConstructorPartList = new ArrayList<>(); field123ConstructorPartList.add(field1ConstructorPart); field123ConstructorPartList.add(field2ConstructorPart); field123ConstructorPartList.add(field3ConstructorPart); Constructor field123Constructor = Constructor.builder() .parts(field123ConstructorPartList) .build(); // Create a list for Field4.Field2.Field1 queries List<ConstructorPart> field421ConstructorPartList = new ArrayList<>(); field421ConstructorPartList.add(field4ConstructorPart); field421ConstructorPartList.add(field2ConstructorPart); field421ConstructorPartList.add(field1ConstructorPart); Constructor field421Constructor = Constructor.builder() .parts(field421ConstructorPartList) .build();
    C# / .NET
    // Create a list for Field1.Field2.Field3 queries var field123ConstructorPartList = new Constructor { Parts = new List<ConstructorPart> { field1ConstructorPart, field2ConstructorPart, field3ConstructorPart } }; // Create a list for Field4.Field2.Field1 queries var field421ConstructorPartList = new Constructor { Parts = new List<ConstructorPart> { field4ConstructorPart, field2ConstructorPart, field1ConstructorPart } };
  3. 創建一個構造函數列表,其中包含您在步驟 2 中創建的所有構造函數。

    Java
    List<Constructor> constructorList = new ArrayList<>(); constructorList.add(field123Constructor) constructorList.add(field421Constructor)
    C# / .NET
    var constructorList = new List<Constructor> { field123Constructor, field421Constructor };
  4. 指定建constructorList立已簽署信標的時間。