本文為英文版的機器翻譯版本,如內容有任何歧義或不一致之處,概以英文版為準。
我們的用戶端加密程式庫已重新命名為 AWS 資料庫加密 SDK。本開發人員指南仍提供 DynamoDB 加密用戶端的相關資訊。 |
有兩種類型的信標支持可搜索的加密。標準信標執行相等搜尋。它們是在數據庫中實現可搜索加密的最簡單方法。複合信標結合常值純文字字串和標準信標,以執行更複雜的查詢。
信標的設計是要在新的、未填入的資料庫中實作。在現有資料庫中設定的任何信標只會對應寫入資料庫的新記錄。信標是根據欄位的純文字值計算的,一旦欄位經過加密,信標就無法對應現有資料。使用信標寫入新記錄之後,就無法更新信標的組態。不過,您可以為新增至記錄的新欄位新增信標。
決定存取模式之後,設定信標應該是實作資料庫的第二個步驟。然後,在設定所有信標之後,您需要建立AWS KMS 階層式金鑰環、定義信標版本、為每個信標設定次要索引、定義加密動作,以及設定資料 AWS 庫和 Database Encryption SDK 用戶端。如需詳細資訊,請參閱使用信標。
為了更容易定義信標版本,我們建議您建立標準和複合信標的清單。在設定時,將您建立的每個信標新增至個別的標準或複合信標清單。
設定標準信標
標準信標是在數據庫中實現可搜索加密的最簡單方法。它們只能針對單一加密或虛擬欄位執行相等搜尋。
設定語法範例
- Java
-
List<StandardBeacon> standardBeaconList = new ArrayList<>();
StandardBeacon exampleStandardBeacon = StandardBeacon.builder()
.name("beaconName
")
.length(beaconLengthInBits)
.build();
standardBeaconList.add(exampleStandardBeacon);
- C# / .NET
-
var standardBeaconList = new List<StandardBeacon>();
StandardBeacon exampleStandardBeacon = new StandardBeacon
{
Name = "beaconName
",
Length = 10
};
standardBeaconList.Add(exampleStandardBeacon);
若要設定標準信標,請提供下列值。
- 信標名稱
-
查詢加密欄位時使用的名稱。
信標名稱可以與加密欄位或虛擬欄位相同的名稱,但不能與未加密欄位的名稱相同。我們強烈建議盡可能使用標準信標建構的加密欄位或虛擬欄位的名稱。兩個不同的信標不能具有相同的信標名稱。如需決定實作之最佳信標名稱的說明,請參閱選擇信標名稱。
- 信標長度
-
截斷之後保留的信標雜湊值位元數目。
信標長度會決定指定信標產生誤報的平均數目。如需詳細資訊並協助判斷實作的適當信標長度,請參閱判斷信標長度。
- 信標來源 (選擇性)
-
建構標準信標的欄位。
信標來源必須是欄位名稱或參照巢狀欄位值的索引。當您的信標名稱與信標來源相同時,您可以省略組態中的信標來源, AWS 資料庫加密 SDK 會自動使用信標名稱作為信標來源。
建立虛擬欄位
若要建立虛擬欄位,您必須提供虛擬欄位的名稱和來源欄位清單。將來源欄位加入至虛擬零件表的順序決定了連接來源欄位以建置虛擬欄位的順序。下列範例將兩個來源欄位全部連結起來,以建立虛擬欄位。
我們建議您在填入資料庫之前,先確認您的虛擬欄位是否會產生預期的結果。如需詳細資訊,請參閱測試信標輸出。
- Java
-
請參閱完整的代碼示例:VirtualBeaconSearchableEncryptionExample.java
List<VirtualPart> virtualPartList = new ArrayList<>();
virtualPartList.add(sourceField1
);
virtualPartList.add(sourceField2
);
VirtualField virtualFieldName
= VirtualField.builder()
.name("virtualFieldName
")
.parts(virtualPartList)
.build();
List<VirtualField> virtualFieldList = new ArrayList<>();
virtualFieldList.add(virtualFieldName
);
- C# / .NET
-
請參閱完整的代碼示例:VirtualBeaconSearchableEncryptionExample.cs
var virtualPartList = new List<VirtualPart> { sourceField1
, sourceField2
};
var virtualFieldName
= new VirtualField
{
Name = "virtualFieldName
",
Parts = virtualPartList
};
var virtualFieldList = new List<VirtualField> { virtualFieldName
};
若要使用來源欄位的特定區段建立虛擬欄位,您必須先定義該轉換,然後再將來源欄位新增至虛擬零件清單。
虛擬欄位的安全性考量
信標不會改變欄位的加密狀態。但是,當您使用信標時,在查詢的效率和披露有關數據分佈的信息量之間存在固有的權衡。您設定信標的方式會決定該信標所保留的安全層級。
避免建立含有與現有標準信標重疊的來源欄位的虛擬欄位。建立包含已用來建立標準信標之來源欄位的虛擬欄位,可降低兩個信標的安全層次。安全性降低的程度取決於其他源字段添加的熵級別。熵層級取決於其他來源欄位中唯一值的分佈,以及其他來源欄位對虛擬欄位整體大小所貢獻的位元數。
您可以使用人口和信標長度來判斷虛擬欄位的來源欄位是否保留資料集的安全性。人口是一個字段中唯一值的預期數量。您的人口不需要精確。有關估計字段人口的幫助,請參閱估計人口。
檢閱虛擬欄位的安全性時,請考慮下列範例。
如果下列陳述式為真,則信標 2 會保留信標 1 和信標 2 的安全性:
N ≥ (Beacon1 length)/2
以及
N ≥ (Beacon2 length)/2
定義信標樣式
標準信標可用於對加密或虛擬欄位執行相等搜尋。或者,它們可用於構建複合信標以執行更複雜的數據庫操作。為了協助您組織及管理標準信標,Datab AWS ase Encryption SDK 提供下列選擇性信標樣式,以定義標準信標的預定用途。
若要定義信標樣式,您必須使用 3.2 版或更新版本的 AWS 資料庫加密 SDK。在將信標樣式新增至信標組態之前,請先將新版本部署至所有讀取器。
- PartOnly
-
定義為的標準信標只PartOnly
能用來定義複合信標的加密部分。您無法直接查詢標PartOnly
準信標。
- Java
-
List<StandardBeacon> standardBeaconList = new ArrayList<>();
StandardBeacon exampleStandardBeacon = StandardBeacon.builder()
.name("beaconName
")
.length(beaconLengthInBits)
.style(
BeaconStyle.builder()
.partOnly(PartOnly.builder().build())
.build()
)
.build();
standardBeaconList.add(exampleStandardBeacon);
- C#/.
-
new StandardBeacon
{
Name = "beaconName
",
Length = beaconLengthInBits,
Style = new BeaconStyle
{
PartOnly = new PartOnly()
}
}
- Shared
-
根據預設,每個標準信標都會產生一個唯一的 HMAC 金鑰來計算信標。因此,您無法對來自兩個不同標準信標的加密欄位執行相等搜尋。定義為Shared
使用其他標準信標的 HMAC 金鑰進行計算的標準信標。
例如,如果您需要將beacon1
欄位與欄位進beacon2
行比較,請定義beacon2
為使用 HMAC 金鑰進行計算beacon1
的Shared
信標。
設定任何Shared
信標之前,請考慮您的安全性和效能需求。 Shared
信標可能會增加可識別的有關數據集分佈的統計信息量。例如,它們可能會顯示哪些共用欄位包含相同的純文字值。
- Java
-
List<StandardBeacon> standardBeaconList = new ArrayList<>();
StandardBeacon exampleStandardBeacon = StandardBeacon.builder()
.name("beacon2
")
.length(beaconLengthInBits)
.style(
BeaconStyle.builder()
.shared(Shared.builder().other("beacon1
").build())
.build()
)
.build();
standardBeaconList.add(exampleStandardBeacon);
- C#/.
-
new StandardBeacon
{
Name = "beacon2
",
Length = beaconLengthInBits,
Style = new BeaconStyle
{
Shared = new Shared { Other = "beacon1
" }
}
}
- AsSet
-
根據預設,如果欄位值是集合, AWS 資料庫加密 SDK 會計算集合的單一標準信標。因此,您無法執行加密欄位的查詢CONTAINS(a
, :value
)
。a
標準信標 (Beacon) 定義為AsSet
計算集合中每個個別元素的個別標準信標值,並以集合形式儲存在項目中的信標值。這可讓資 AWS 料庫加密 SDK 執行查詢CONTAINS(a
, :value
)
。
若要定義AsSet
標準信標,集合中的元素必須來自相同的人口,以便它們都可以使用相同的信標長度。如果在計算信標值時發生衝突,信標集合的元素可能會少於純文字集。
設定任何AsSet
信標之前,請考慮您的安全性和效能需求。 AsSet
信標可能會增加可識別的有關數據集分佈的統計信息量。例如,它們可能會顯示明文集的大小。
- Java
-
List<StandardBeacon> standardBeaconList = new ArrayList<>();
StandardBeacon exampleStandardBeacon = StandardBeacon.builder()
.name("beaconName
")
.length(beaconLengthInBits)
.style(
BeaconStyle.builder()
.asSet(AsSet.builder().build())
.build()
)
.build();
standardBeaconList.add(exampleStandardBeacon);
- C#/.
-
new StandardBeacon
{
Name = "beaconName
",
Length = beaconLengthInBits,
Style = new BeaconStyle
{
AsSet = new AsSet()
}
}
- SharedSet
-
定義為SharedSet
結合Shared
和AsSet
函數的標準信標,以便您可以對集合和欄位的加密值執行相等搜尋。這使得 AWS 數據庫加密 SDK 能夠執行查詢,CONTAINS(a
, b
)
其中a
是加密集,並且b
是一個加密的字段。
設定任何Shared
信標之前,請考慮您的安全性和效能需求。 SharedSet
信標可能會增加可識別的有關數據集分佈的統計信息量。例如,它們可能會顯示純文字集的大小,或哪些共用欄位包含相同的純文字值。
- Java
-
List<StandardBeacon> standardBeaconList = new ArrayList<>();
StandardBeacon exampleStandardBeacon = StandardBeacon.builder()
.name("beacon2
")
.length(beaconLengthInBits)
.style(
BeaconStyle.builder()
.sharedSet(SharedSet.builder().other("beacon1
").build())
.build()
)
.build();
standardBeaconList.add(exampleStandardBeacon);
- C#/.
-
new StandardBeacon
{
Name = "beacon2
",
Length = beaconLengthInBits,
Style = new BeaconStyle
{
SharedSet = new SharedSet { Other = "beacon1
" }
}
}
設定複合信標
複合信標會結合常值純文字字串和標準信標,以執行複雜的資料庫作業,例如從單一索引查詢兩種不同的記錄類型,或使用排序索引鍵查詢欄位組合。複合信標可以從ENCRYPT_AND_SIGN
SIGN_ONLY
、和SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT
字段構造。您必須為複合信標中包含的每個加密欄位建立標準信標。
我們建議您在填入資料庫之前,先確認您的複合信標產生預期的結果。如需詳細資訊,請參閱測試信標輸出。
設定語法範例
- Java
-
複合信標配置
下列範例會在複合信標組態中於本機定義加密和已簽署的零件清單。
List<CompoundBeacon> compoundBeaconList = new ArrayList<>();
CompoundBeacon exampleCompoundBeacon = CompoundBeacon.builder()
.name("compoundBeaconName
")
.split(".
")
.encrypted(encryptedPartList)
.signed(signedPartList)
.constructors(constructorList)
.build();
compoundBeaconList.add(exampleCompoundBeacon);
信標版本定義
下列範例會在信標版本中全域定義加密和已簽署的零件清單。如需有關定義信標版本的詳細資訊,請參閱使用信標。
List<BeaconVersion> beaconVersions = new ArrayList<>();
beaconVersions.add(
BeaconVersion.builder()
.standardBeacons(standardBeaconList)
.compoundBeacons(compoundBeaconList)
.encryptedParts(encryptedPartList)
.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
複合信標配置
下列範例會在複合信標組態中於本機定義加密和已簽署的零件清單。
var compoundBeaconList = new List<CompoundBeacon>();
var exampleCompoundBeacon = new CompoundBeacon
{
Name = "compoundBeaconName
",
Split = ".
",
Encrypted = encryptedPartList,
Signed = signedPartList,
Constructors = constructorList
};
compoundBeaconList.Add(exampleCompoundBeacon);
信標版本定義
下列範例會在信標版本中全域定義加密和已簽署的零件清單。如需有關定義信標版本的詳細資訊,請參閱使用信標。
var beaconVersions = new List<BeaconVersion>
{
new BeaconVersion
{
StandardBeacons = standardBeaconList,
CompoundBeacons = compoundBeaconList,
EncryptedParts = encryptedPartsList,
SignedParts = signedPartsList,
Version = 1, // MUST be 1
KeyStore = keyStore,
KeySource = new BeaconKeySource
{
Single = new SingleKeyStore
{
KeyId = branchKeyId,
CacheTTL = 6000
}
}
}
};
您可以在本機或全域定義的清單中定義加密零件和已簽署零件。我們建議盡可能在信標版本的全域清單中定義加密和簽署的零件。透過全域定義加密和簽署的零件,您可以定義每個零件一次,然後在多個複合信標 (Beacon) 組態中重複使用零件。如果您只打算使用一次加密或已簽署的零件,則可以在複合信標組態的本機清單中定義該零件。您可以在構造函數列表中引用本地和全局部分。
如果您全域定義加密和已簽署的零件清單,則必須提供建構函式零件清單,以識別複合信標在複合信標組態中組合欄位的所有可能方式。
若要全域定義加密和已簽署的零件清單,您必須使用 3.2 版或更新版本的 AWS 資料庫加密 SDK。在全域定義任何新零件之前,請先將新版本部署至所有讀取器。
您無法更新現有信標組態,以全域定義加密和已簽署的零件清單。
若要設定複合信標,請提供下列值。
- 信標名稱
-
查詢加密欄位時使用的名稱。
信標名稱可以與加密欄位或虛擬欄位相同的名稱,但不能與未加密欄位的名稱相同。沒有兩個信標可以具有相同的信標名稱。如需決定實作之最佳信標名稱的說明,請參閱選擇信標名稱。
- 分割字元
-
用於分隔組成複合信標的部分的字符。
分割字元不能出現在複合信標所建構之任何欄位的純文字值中。
- 加密零件清單
-
識別複合信標中包含的ENCRYPT_AND_SIGN
欄位。
每個零件都必須包含名稱和字首。零件名稱必須是從加密欄位建構的標準信標的名稱。前綴可以是任何字符串,但它必須是唯一的。加密零件不能具有與已簽署零件相同的字首。我們建議使用短值來區分零件與複合信標服務的其他零件。
我們建議您盡可能在全域定義加密零件。如果您只打算在一個複合信標中使用加密零件,則可以考慮在本機定義加密零件。本機定義的加密零件不能具有與全域定義的加密零件相同的字首或名稱。
- Java
-
List<EncryptedPart> encryptedPartList = new ArrayList<>);
EncryptedPart encryptedPartExample = EncryptedPart.builder()
.name("standardBeaconName
")
.prefix("E-")
.build();
encryptedPartList.add(encryptedPartExample);
- C# / .NET
-
var encryptedPartList = new List<EncryptedPart>();
var encryptedPartExample = new EncryptedPart
{
Name = "compoundBeaconName
",
Prefix = "E-"
};
encryptedPartList.Add(encryptedPartExample);
- 已簽署零件清單
-
識別複合信標中包含的已簽署欄位。
簽署的零件是選用的。您可以設定不參照任何已簽署零件的複合信標。
每個零件都必須包含名稱、來源和字首。來源是零件識別的SIGN_ONLY
或SIGN_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 會使用下列預設建構函式組合複合信標。
- 建構函式
-
每個構造函數都是構造函數部分的有序列表,它定義了可以組裝複合信標的一種方式。構造函數部分按照它們被添加到列表中的順序連接在一起,每個部分由指定的拆分字符分隔。
每個構造函數部分命名一個加密的部分或一個簽名的部分,並定義構造函數中該部分是必需的還是可選的。例如,如果您想在、和Field1.Field2.Field3
上查詢複合信標 Field1
Field1.Field2
,請將 and 標記Field3
為可選Field2
並創建一個構造函數。
每個構造函數必須至少有一個必需的部分。我們建議在每個所需的構造函數中進行第一部分,以便您可以在查詢中使用BEGINS_WITH
運算符。
如果記錄中存在其所有必需的部分,則構造函數成功。當您撰寫新記錄時,複合信標會使用建構函式清單來判斷是否可以從提供的值組合信標。它嘗試按照構造函數添加到構造函數列表的順序組裝信標,並使用成功的第一個構造函數。如果沒有建構函式成功,就不會將信標寫入記錄。
所有讀者和作者都應該指定相同的構造函數順序,以確保他們的查詢結果是正確的。
請使用下列程序來指定您自己的建構函式清單。
-
為每個加密零件和已簽署的零件建立建構函式零件,以定義是否需要該零件。
構造函數部分名稱必須是它表示的標準信標或帶符號字段的名稱。
- Java
-
ConstructorPart field1ConstructorPart = ConstructorPart.builder()
.name("Field1
")
.required(true
)
.build();
- C# / .NET
-
var field1ConstructorPart = new ConstructorPart { Name = "Field1
", Required = true
};
-
為可以使用您在步驟 1 中創建的構造函數部件組裝複合信標的每種可能方式創建構函數。
例如,如果你想查詢Field1.Field2.Field3
和Field4.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 }
};
-
創建一個構造函數列表,其中包含您在步驟 2 中創建的所有構造函數。
- Java
-
List<Constructor> constructorList = new ArrayList<>();
constructorList.add(field123Constructor)
constructorList.add(field421Constructor)
- C# / .NET
-
var constructorList = new List<Constructor>
{
field123Constructor,
field421Constructor
};
-
指定建constructorList
立複合信標的時間。