Skip to content

Commit 02d7b0a

Browse files
committed
m
1 parent 088a7dc commit 02d7b0a

File tree

5 files changed

+509
-0
lines changed

5 files changed

+509
-0
lines changed
Lines changed: 144 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,144 @@
1+
use std::collections::HashMap;
2+
use crate::test_utils;
3+
use aws_sdk_dynamodb::types::AttributeValue;
4+
5+
use db_esdk::deps::aws_cryptography_materialProviders::types::material_providers_config::MaterialProvidersConfig;
6+
use db_esdk::deps::aws_cryptography_materialProviders::client as mpl_client;
7+
use db_esdk::deps::aws_cryptography_dbEncryptionSdk_structuredEncryption::types::CryptoAction;
8+
9+
use db_esdk::deps::aws_cryptography_dbEncryptionSdk_dynamoDb_itemEncryptor::types::dynamo_db_item_encryptor_config::DynamoDbItemEncryptorConfig;
10+
use db_esdk::deps::aws_cryptography_dbEncryptionSdk_dynamoDb_itemEncryptor::client as enc_client;
11+
use db_esdk::deps::aws_cryptography_materialProviders::types::DbeAlgorithmSuiteId;
12+
13+
/*
14+
This example sets up a DynamoDb Item Encryptor and uses
15+
the EncryptItem and DecryptItem APIs to directly encrypt and
16+
decrypt an existing DynamoDb item.
17+
You should use the DynamoDb Item Encryptor
18+
if you already have a DynamoDb Item to encrypt or decrypt,
19+
and do not need to make a Put or Get call to DynamoDb.
20+
For example, if you are using DynamoDb Streams,
21+
you may already be working with an encrypted item obtained from
22+
DynamoDb, and want to directly decrypt the item.
23+
24+
Running this example requires access to the DDB Table whose name
25+
is provided in CLI arguments.
26+
This table must be configured with the following
27+
primary key configuration:
28+
- Partition key is named "partition_key" with type (S)
29+
- Sort key is named "sort_key" with type (S)
30+
*/
31+
pub async fn encrypt_decrypt()
32+
{
33+
let kms_key_id = test_utils::TEST_KMS_KEY_ID;
34+
let ddb_table_name = test_utils::TEST_DDB_TABLE_NAME;
35+
36+
37+
// 1. Create a Keyring. This Keyring will be responsible for protecting the data keys that protect your data.
38+
// For this example, we will create a AWS KMS Keyring with the AWS KMS Key we want to use.
39+
// We will use the `CreateMrkMultiKeyring` method to create this keyring,
40+
// as it will correctly handle both single region and Multi-Region KMS Keys.
41+
let provider_config = MaterialProvidersConfig::builder().build().unwrap();
42+
let mat_prov = mpl_client::Client::from_conf(provider_config).unwrap();
43+
let kms_keyring = mat_prov.create_aws_kms_mrk_multi_keyring().generator(kms_key_id).send().await.unwrap();
44+
45+
// 2. Configure which attributes are encrypted and/or signed when writing new items.
46+
// For each attribute that may exist on the items we plan to write to our DynamoDbTable,
47+
// we must explicitly configure how they should be treated during item encryption:
48+
// - ENCRYPT_AND_SIGN: The attribute is encrypted and included in the signature
49+
// - SIGN_ONLY: The attribute not encrypted, but is still included in the signature
50+
// - DO_NOTHING: The attribute is not encrypted and not included in the signature
51+
let attribute_actions_on_encrypt = HashMap::from([
52+
("partition_key".to_string(), CryptoAction::SignOnly),
53+
("sort_key".to_string(), CryptoAction::SignOnly),
54+
("attribute1".to_string(), CryptoAction::EncryptAndSign),
55+
("attribute2".to_string(), CryptoAction::SignOnly),
56+
(":attribute3".to_string(), CryptoAction::DoNothing),
57+
]);
58+
59+
// 3. Configure which attributes we expect to be included in the signature
60+
// when reading items. There are two options for configuring this:
61+
//
62+
// - (Recommended) Configure `allowedUnsignedAttributesPrefix`:
63+
// When defining your DynamoDb schema and deciding on attribute names,
64+
// choose a distinguishing prefix (such as ":") for all attributes that
65+
// you do not want to include in the signature.
66+
// This has two main benefits:
67+
// - It is easier to reason about the security and authenticity of data within your item
68+
// when all unauthenticated data is easily distinguishable by their attribute name.
69+
// - If you need to add new unauthenticated attributes in the future,
70+
// you can easily make the corresponding update to your `attributeActionsOnEncrypt`
71+
// and immediately start writing to that new attribute, without
72+
// any other configuration update needed.
73+
// Once you configure this field, it is not safe to update it.
74+
//
75+
// - Configure `allowedUnsignedAttributes`: You may also explicitly list
76+
// a set of attributes that should be considered unauthenticated when encountered
77+
// on read. Be careful if you use this configuration. Do not remove an attribute
78+
// name from this configuration, even if you are no longer writing with that attribute,
79+
// as old items may still include this attribute, and our configuration needs to know
80+
// to continue to exclude this attribute from the signature scope.
81+
// If you add new attribute names to this field, you must first deploy the update to this
82+
// field to all readers in your host fleet before deploying the update to start writing
83+
// with that new attribute.
84+
//
85+
// For this example, we have designed our DynamoDb table such that any attribute name with
86+
// the ":" prefix should be considered unauthenticated.
87+
const UNSIGNED_ATTR_PREFIX : &str = ":";
88+
89+
// 4. Create the configuration for the DynamoDb Item Encryptor
90+
let config = DynamoDbItemEncryptorConfig::builder()
91+
.logical_table_name(ddb_table_name)
92+
.partition_key_name("partition_key")
93+
.sort_key_name("sort_key")
94+
.attribute_actions_on_encrypt(attribute_actions_on_encrypt)
95+
.keyring(kms_keyring)
96+
.allowed_unsigned_attribute_prefix(UNSIGNED_ATTR_PREFIX)
97+
// Specifying an algorithm suite is not required,
98+
// but is done here to demonstrate how to do so.
99+
// We suggest using the
100+
// `ALG_AES_256_GCM_HKDF_SHA512_COMMIT_KEY_ECDSA_P384_SYMSIG_HMAC_SHA384` suite,
101+
// which includes AES-GCM with key derivation, signing, and key commitment.
102+
// This is also the default algorithm suite if one is not specified in this config.
103+
// For more information on supported algorithm suites, see:
104+
// https://docs.aws.amazon.com/database-encryption-sdk/latest/devguide/supported-algorithms.html
105+
.algorithm_suite_id(DbeAlgorithmSuiteId::AlgAes256GcmHkdfSha512CommitKeyEcdsaP384SymsigHmacSha384)
106+
.build().unwrap();
107+
108+
// 5. Create the DynamoDb Item Encryptor
109+
let item_encryptor = enc_client::Client::from_conf(config).unwrap();
110+
111+
// 6. Directly encrypt a DynamoDb item using the DynamoDb Item Encryptor
112+
let original_item = HashMap::from([
113+
("partition_key".to_string(), AttributeValue::S("ItemEncryptDecryptExample".to_string())),
114+
("sort_key".to_string(), AttributeValue::N("0".to_string())),
115+
("attribute1".to_string(), AttributeValue::S("encrypt and sign me!".to_string())),
116+
("attribute2".to_string(), AttributeValue::S("sign me!".to_string())),
117+
(":attribute3".to_string(), AttributeValue::S("ignore me!".to_string())),
118+
]);
119+
120+
let encrypted_item = item_encryptor.encrypt_item()
121+
.plaintext_item(original_item.clone())
122+
.send()
123+
.await
124+
.unwrap()
125+
.encrypted_item.unwrap();
126+
127+
// Demonstrate that the item has been encrypted
128+
assert_eq!(encrypted_item["partition_key"], AttributeValue::S("ItemEncryptDecryptExample".to_string()));
129+
assert_eq!(encrypted_item["sort_key"], AttributeValue::N("0".to_string()));
130+
assert!(encrypted_item["attribute1"].is_b());
131+
assert!(!encrypted_item["attribute1"].is_s());
132+
133+
// 7. Directly decrypt the encrypted item using the DynamoDb Item Encryptor
134+
let decrypted_item = item_encryptor.decrypt_item()
135+
.encrypted_item(encrypted_item)
136+
.send()
137+
.await
138+
.unwrap()
139+
.plaintext_item.unwrap();
140+
141+
// Demonstrate that GetItem succeeded and returned the decrypted item
142+
assert_eq!(decrypted_item, original_item);
143+
println!("encrypt_decrypt successful.");
144+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
pub mod item_encrypt_decrypt;
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,39 @@
11

22
pub mod basic_get_put_example;
33
pub mod test_utils;
4+
pub mod itemencryptor;
5+
pub mod searchableencryption;
46

57
#[tokio::main]
68
pub async fn main() {
79
basic_get_put_example::put_item_get_item().await;
10+
itemencryptor::item_encrypt_decrypt::encrypt_decrypt().await;
11+
/*
12+
13+
await ScanErrorExample.ScanError();
14+
await GetEncryptedDataKeyDescriptionExample.GetEncryptedDataKeyDescription();
15+
await MultiPutGetExample.MultiPutGet();
16+
await ClientSupplierExample.ClientSupplierPutItemGetItem();
17+
await MultiMrkKeyringExample.MultiMrkKeyringGetItemPutItem();
18+
await RawAesKeyringExample.RawAesKeyringGetItemPutItem();
19+
await MrkDiscoveryMultiKeyringExample.MultiMrkDiscoveryKeyringGetItemPutItem();
20+
await MultiKeyringExample.MultiKeyringGetItemPutItem();
21+
await RawRsaKeyringExample.RawRsaKeyringGetItemPutItem();
22+
await KmsRsaKeyringExample.KmsRsaKeyringGetItemPutItem();
23+
24+
var keyId = CreateKeyStoreKeyExample.KeyStoreCreateKey();
25+
var keyId2 = CreateKeyStoreKeyExample.KeyStoreCreateKey();
26+
// Key creation is eventually consistent, so wait 5 seconds to decrease the likelihood
27+
// our test fails due to eventual consistency issues.
28+
Thread.Sleep(5000);
29+
30+
await HierarchicalKeyringExample.HierarchicalKeyringGetItemPutItem(keyId, keyId2);
31+
32+
await BasicSearchableEncryptionExample.PutItemQueryItemWithBeacon(keyId);
33+
await CompoundBeaconSearchableEncryptionExample.PutItemQueryItemWithCompoundBeacon(keyId);
34+
await VirtualBeaconSearchableEncryptionExample.PutItemQueryItemWithVirtualBeacon(keyId);
35+
await BeaconStylesSearchableEncryptionExample.PutItemQueryItemWithBeaconStyles(keyId);
36+
await ComplexSearchableEncryptionExample.RunExample(keyId);
37+
Console.Write("All examples completed successfully.\n");
38+
*/
839
}

0 commit comments

Comments
 (0)