翻訳は機械翻訳により提供されています。提供された翻訳内容と英語版の間で齟齬、不一致または矛盾がある場合、英語版が優先します。
データキーキャッシュを使用する方法
このトピックでは、アプリケーションのデータキーキャッシュを使用する方法について説明します。ここでは、プロセスを手順ごとに説明します。次に、文字列を暗号化するオペレーションでデータキーキャッシュを使用する簡単な例の中ですべての手順を結びつけます。
このセクションの例では、 AWS Encryption SDKのバージョン 2.0.x 以降の使用方法について説明します。以前のバージョンを使用する例については、プログラミング言語 の GitHub リポジトリのリリース
でデータキーキャッシュを使用するための完全でテスト済みの例については AWS Encryption SDK、「」を参照してください。
-
C/C++: caching_cmm.cpp
JavaScript ブラウザ: caching_cmm.ts
JavaScript Node.js: caching_cmm.ts
-
Python: data_key_caching_basic.py
for AWS Encryption SDK 。 NETはデータキーキャッシュをサポートしていません。
データキーキャッシュの使用: Step-by-step
これらの step-by-step手順は、データキーキャッシュを実装するために必要なコンポーネントを作成する方法を示しています。
-
データキーキャッシュを作成します。これらの例では、 AWS Encryption SDK が提供するローカルキャッシュを使用します。キャッシュは、10 個のデータキーに制限されています。
- C
-
// Cache capacity (maximum number of entries) is required size_t cache_capacity = 10; struct aws_allocator *allocator = aws_default_allocator(); struct aws_cryptosdk_materials_cache *cache = aws_cryptosdk_materials_cache_local_new(allocator, cache_capacity);
- Java
-
次の例では、 のバージョン 2.x を使用します AWS Encryption SDK for Java。のバージョン 3.x では、データキーキャッシュ は AWS Encryption SDK for Java 廃止されますCMM。バージョン 3.x では、代替暗号化マテリアルキャッシュソリューションであるAWS KMS 階層キーリング を使用することもできます。
// Cache capacity (maximum number of entries) is required int MAX_CACHE_SIZE = 10; CryptoMaterialsCache cache = new LocalCryptoMaterialsCache(MAX_CACHE_SIZE);
- JavaScript Browser
-
const capacity = 10 const cache = getLocalCryptographicMaterialsCache(capacity)
- JavaScript Node.js
-
const capacity = 10 const cache = getLocalCryptographicMaterialsCache(capacity)
- Python
-
# Cache capacity (maximum number of entries) is required MAX_CACHE_SIZE = 10 cache = aws_encryption_sdk.LocalCryptoMaterialsCache(MAX_CACHE_SIZE)
-
マスターキープロバイダー (Java と Python) またはキーリング (C と ) を作成します JavaScript。これらの例では、 AWS Key Management Service (AWS KMS) マスターキープロバイダーまたは互換性のあるAWS KMS キーリング を使用します。
- C
-
// Create an AWS KMS keyring // The input is the Amazon Resource Name (ARN) // of an AWS KMS key struct aws_cryptosdk_keyring *kms_keyring = Aws::Cryptosdk::KmsKeyring::Builder().Build(kms_key_arn);
- Java
-
次の例では、 のバージョン 2.x を使用します AWS Encryption SDK for Java。のバージョン 3.x は、データキーキャッシュ を AWS Encryption SDK for Java 廃止しますCMM。バージョン 3.x では、代替暗号化マテリアルキャッシュソリューションであるAWS KMS 階層キーリング を使用することもできます。
// Create an AWS KMS master key provider // The input is the Amazon Resource Name (ARN) // of an AWS KMS key MasterKeyProvider<KmsMasterKey> keyProvider = KmsMasterKeyProvider.builder().buildStrict(kmsKeyArn);
- JavaScript Browser
-
ブラウザでは、認証情報を安全に挿入する必要があります。この例では、ランタイムに認証情報を解決する Webpack (kms.webpack.config) の認証情報を定義します。 AWS KMS クライアントと認証情報から AWS KMS クライアントプロバイダーインスタンスを作成します。次に、キーリングを作成すると、 AWS KMS key () とともにクライアントプロバイダーをコンストラクターに渡します
generatorKeyId)
。const { accessKeyId, secretAccessKey, sessionToken } = credentials const clientProvider = getClient(KMS, { credentials: { accessKeyId, secretAccessKey, sessionToken } }) /* Create an AWS KMS keyring * You must configure the AWS KMS keyring with at least one AWS KMS key * The input is the Amazon Resource Name (ARN) */ of an AWS KMS key const keyring = new KmsKeyringBrowser({ clientProvider, generatorKeyId, keyIds, })
- JavaScript Node.js
/* Create an AWS KMS keyring * The input is the Amazon Resource Name (ARN) */ of an AWS KMS key const keyring = new KmsKeyringNode({ generatorKeyId })
- Python
-
# Create an AWS KMS master key provider # The input is the Amazon Resource Name (ARN) # of an AWS KMS key key_provider = aws_encryption_sdk.StrictAwsKmsMasterKeyProvider(key_ids=[kms_key_arn])
-
キャッシュ暗号化マテリアルマネージャー (キャッシュ ) を作成します。 CMM
キャッシュをキャッシュとマスターキープロバイダーまたはキーリングCMMに関連付けます。次に、キャッシュ にキャッシュセキュリティしきい値を設定しますCMM。
- C
-
では AWS Encryption SDK for C、デフォルトの CMMなどの基盤となる CMMからCMM、またはキーリングからキャッシュを作成できます。この例では、キーリングCMMからキャッシュを作成します。
キャッシュを作成したらCMM、キーリングとキャッシュへの参照を解放できます。詳細については、「参照カウント」を参照してください。
// Create the caching CMM // Set the partition ID to NULL. // Set the required maximum age value to 60 seconds. struct aws_cryptosdk_cmm *caching_cmm = aws_cryptosdk_caching_cmm_new_from_keyring(allocator, cache, kms_keyring, NULL, 60, AWS_TIMESTAMP_SECS); // Add an optional message threshold // The cached data key will not be used for more than 10 messages. aws_status = aws_cryptosdk_caching_cmm_set_limit_messages(caching_cmm, 10); // Release your references to the cache and the keyring. aws_cryptosdk_materials_cache_release(cache); aws_cryptosdk_keyring_release(kms_keyring);
- Java
-
次の例では、 のバージョン 2.x を使用します AWS Encryption SDK for Java。のバージョン 3.x AWS Encryption SDK for Java はデータキーキャッシュをサポートしていませんが、代替暗号化マテリアルキャッシュソリューションであるAWS KMS 階層キーリング をサポートしています。
/* * Security thresholds * Max entry age is required. * Max messages (and max bytes) per entry are optional */ int MAX_ENTRY_AGE_SECONDS = 60; int MAX_ENTRY_MSGS = 10; //Create a caching CMM CryptoMaterialsManager cachingCmm = CachingCryptoMaterialsManager.newBuilder().withMasterKeyProvider(keyProvider) .withCache(cache) .withMaxAge(MAX_ENTRY_AGE_SECONDS, TimeUnit.SECONDS) .withMessageUseLimit(MAX_ENTRY_MSGS) .build();
- JavaScript Browser
/* * Security thresholds * Max age (in milliseconds) is required. * Max messages (and max bytes) per entry are optional. */ const maxAge = 1000 * 60 const maxMessagesEncrypted = 10 /* Create a caching CMM from a keyring */ const cachingCmm = new WebCryptoCachingMaterialsManager({ backingMaterials: keyring, cache, maxAge, maxMessagesEncrypted })
- JavaScript Node.js
/* * Security thresholds * Max age (in milliseconds) is required. * Max messages (and max bytes) per entry are optional. */ const maxAge = 1000 * 60 const maxMessagesEncrypted = 10 /* Create a caching CMM from a keyring */ const cachingCmm = new NodeCachingMaterialsManager({ backingMaterials: keyring, cache, maxAge, maxMessagesEncrypted })
- Python
-
# Security thresholds # Max entry age is required. # Max messages (and max bytes) per entry are optional # MAX_ENTRY_AGE_SECONDS = 60.0 MAX_ENTRY_MESSAGES = 10 # Create a caching CMM caching_cmm = CachingCryptoMaterialsManager( master_key_provider=key_provider, cache=cache, max_age=MAX_ENTRY_AGE_SECONDS, max_messages_encrypted=MAX_ENTRY_MESSAGES )
必要な作業はこれだけです。次に、 がキャッシュ AWS Encryption SDK を管理できるようにするか、独自のキャッシュ管理ロジックを追加します。
呼び出しでデータキーキャッシュを使用してデータを暗号化または復号する場合は、マスターキープロバイダーやその他の CMMの代わりにキャッシュを指定しますCMM。
注記
データストリーム、または不明なサイズのデータを暗号化している場合、必ずリクエストでデータサイズを指定してください。 AWS Encryption SDK は、不明なサイズのデータを暗号化するときにデータキーキャッシュを使用しません。
- C
-
で AWS Encryption SDK for C、キャッシュを使用してセッションを作成しCMM、セッションを処理します。
デフォルトでは、メッセージサイズが不明で制限されていない場合、 AWS Encryption SDK はデータキーをキャッシュしません。正確なデータサイズが不明な場合にキャッシュを許可するには、
aws_cryptosdk_session_set_message_bound
メソッドを使用してメッセージに最大サイズを設定します。推定メッセージサイズよりも大きい境界を設定します。実際のメッセージサイズが制限を超えると、暗号化オペレーションは失敗します。/* Create a session with the caching CMM. Set the session mode to encrypt. */ struct aws_cryptosdk_session *session = aws_cryptosdk_session_new_from_cmm_2(allocator, AWS_CRYPTOSDK_ENCRYPT, caching_cmm); /* Set a message bound of 1000 bytes */ aws_status = aws_cryptosdk_session_set_message_bound(session, 1000); /* Encrypt the message using the session with the caching CMM */ aws_status = aws_cryptosdk_session_process( session, output_buffer, output_capacity, &output_produced, input_buffer, input_len, &input_consumed); /* Release your references to the caching CMM and the session. */ aws_cryptosdk_cmm_release(caching_cmm); aws_cryptosdk_session_destroy(session);
- Java
-
次の例では、 のバージョン 2.x を使用します AWS Encryption SDK for Java。のバージョン 3.x は、データキーキャッシュ を AWS Encryption SDK for Java 廃止しますCMM。バージョン 3.x では、代替暗号化マテリアルキャッシュソリューションであるAWS KMS 階層キーリング を使用することもできます。
// When the call to encryptData specifies a caching CMM, // the encryption operation uses the data key cache final AwsCrypto encryptionSdk = AwsCrypto.standard(); return encryptionSdk.encryptData(cachingCmm, plaintext_source).getResult();
- JavaScript Browser
-
const { result } = await encrypt(cachingCmm, plaintext)
- JavaScript Node.js
-
AWS Encryption SDK for JavaScript for Node.js CMMでキャッシュを使用する場合、
encrypt
メソッドにはプレーンテキストの長さが必要です。これを指定しないと、データキーはキャッシュされません。長さを指定しても、指定した平文データがその長さを超えると、暗号化オペレーションは失敗します。データのストリーミング時など、平文の正確な長さがわからない場合は、期待される最大の値を指定します。const { result } = await encrypt(cachingCmm, plaintext, { plaintextLength: plaintext.length })
- Python
-
# Set up an encryption client client = aws_encryption_sdk.EncryptionSDKClient() # When the call to encrypt specifies a caching CMM, # the encryption operation uses the data key cache # encrypted_message, header = client.encrypt( source=plaintext_source, materials_manager=caching_cmm )
データキーキャッシュの例: 文字列を暗号化する
このシンプルなコード例では、文字列を暗号化するときにデータキーキャッシュを使用します。step-by-step プロシージャのコードを実行できるテストコードに結合します。
この例では、ローカルキャッシュとマスターキープロバイダーまたはキーリングを AWS KMS keyのために作成します。次に、ローカルキャッシュとマスターキープロバイダーまたはキーリングを使用して、適切なセキュリティしきい値 CMMでキャッシュを作成します。Java および Python では、暗号化リクエストはキャッシュ CMM、暗号化するプレーンテキストデータ、および暗号化コンテキスト を指定します。C では、キャッシュCMMはセッションで指定され、セッションは暗号化リクエストに提供されます。
これらの例を実行するには、 の Amazon リソースネーム (ARN) AWS KMS keyを指定する必要があります。データキーを生成するために、AWS KMS keyを使用するためのアクセス許可 があるかどうか必ず確認してください。
データキーキャッシュの作成と使用に関するさらに詳細な実例については、「データキーキャッシュのコード例」を参照してください。
- C
-
/* * Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"). You may not use * this file except in compliance with the License. A copy of the License is * located at * * http://aws.amazon.com/apache2.0/ * * or in the "license" file accompanying this file. This file is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or * implied. See the License for the specific language governing permissions and * limitations under the License. */ #include <aws/cryptosdk/cache.h> #include <aws/cryptosdk/cpp/kms_keyring.h> #include <aws/cryptosdk/session.h> void encrypt_with_caching( uint8_t *ciphertext, // output will go here (assumes ciphertext_capacity bytes already allocated) size_t *ciphertext_len, // length of output will go here size_t ciphertext_capacity, const char *kms_key_arn, int max_entry_age, int cache_capacity) { const uint64_t MAX_ENTRY_MSGS = 100; struct aws_allocator *allocator = aws_default_allocator(); // Load error strings for debugging aws_cryptosdk_load_error_strings(); // Create a keyring struct aws_cryptosdk_keyring *kms_keyring = Aws::Cryptosdk::KmsKeyring::Builder().Build(kms_key_arn); // Create a cache struct aws_cryptosdk_materials_cache *cache = aws_cryptosdk_materials_cache_local_new(allocator, cache_capacity); // Create a caching CMM struct aws_cryptosdk_cmm *caching_cmm = aws_cryptosdk_caching_cmm_new_from_keyring( allocator, cache, kms_keyring, NULL, max_entry_age, AWS_TIMESTAMP_SECS); if (!caching_cmm) abort(); if (aws_cryptosdk_caching_cmm_set_limit_messages(caching_cmm, MAX_ENTRY_MSGS)) abort(); // Create a session struct aws_cryptosdk_session *session = aws_cryptosdk_session_new_from_cmm_2(allocator, AWS_CRYPTOSDK_ENCRYPT, caching_cmm); if (!session) abort(); // Encryption context struct aws_hash_table *enc_ctx = aws_cryptosdk_session_get_enc_ctx_ptr_mut(session); if (!enc_ctx) abort(); AWS_STATIC_STRING_FROM_LITERAL(enc_ctx_key, "purpose"); AWS_STATIC_STRING_FROM_LITERAL(enc_ctx_value, "test"); if (aws_hash_table_put(enc_ctx, enc_ctx_key, (void *)enc_ctx_value, NULL)) abort(); // Plaintext data to be encrypted const char *my_data = "My plaintext data"; size_t my_data_len = strlen(my_data); if (aws_cryptosdk_session_set_message_size(session, my_data_len)) abort(); // When the session uses a caching CMM, the encryption operation uses the data key cache // specified in the caching CMM. size_t bytes_read; if (aws_cryptosdk_session_process( session, ciphertext, ciphertext_capacity, ciphertext_len, (const uint8_t *)my_data, my_data_len, &bytes_read)) abort(); if (!aws_cryptosdk_session_is_done(session) || bytes_read != my_data_len) abort(); aws_cryptosdk_session_destroy(session); aws_cryptosdk_cmm_release(caching_cmm); aws_cryptosdk_materials_cache_release(cache); aws_cryptosdk_keyring_release(kms_keyring); }
- Java
-
次の例では、 のバージョン 2.x を使用しています AWS Encryption SDK for Java。のバージョン 3.x は、データキーキャッシュ を AWS Encryption SDK for Java 廃止しますCMM。バージョン 3.x では、代替暗号化マテリアルキャッシュソリューションであるAWS KMS 階層キーリング を使用することもできます。
// Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 package com.amazonaws.crypto.examples; import com.amazonaws.encryptionsdk.AwsCrypto; import com.amazonaws.encryptionsdk.CryptoMaterialsManager; import com.amazonaws.encryptionsdk.MasterKeyProvider; import com.amazonaws.encryptionsdk.caching.CachingCryptoMaterialsManager; import com.amazonaws.encryptionsdk.caching.CryptoMaterialsCache; import com.amazonaws.encryptionsdk.caching.LocalCryptoMaterialsCache; import com.amazonaws.encryptionsdk.kmssdkv2.KmsMasterKey; import com.amazonaws.encryptionsdk.kmssdkv2.KmsMasterKeyProvider; import java.nio.charset.StandardCharsets; import java.util.Collections; import java.util.Map; import java.util.concurrent.TimeUnit; /** * <p> * Encrypts a string using an &KMS; key and data key caching * * <p> * Arguments: * <ol> * <li>KMS Key ARN: To find the Amazon Resource Name of your &KMS; key, * see 'Find the key ID and ARN' at https://docs.aws.amazon.com/kms/latest/developerguide/find-cmk-id-arn.html * <li>Max entry age: Maximum time (in seconds) that a cached entry can be used * <li>Cache capacity: Maximum number of entries in the cache * </ol> */ public class SimpleDataKeyCachingExample { /* * Security thresholds * Max entry age is required. * Max messages (and max bytes) per data key are optional */ private static final int MAX_ENTRY_MSGS = 100; public static byte[] encryptWithCaching(String kmsKeyArn, int maxEntryAge, int cacheCapacity) { // Plaintext data to be encrypted byte[] myData = "My plaintext data".getBytes(StandardCharsets.UTF_8); // Encryption context // Most encrypted data should have an associated encryption context // to protect integrity. This sample uses placeholder values. // For more information see: // blogs.aws.amazon.com/security/post/Tx2LZ6WBJJANTNW/How-to-Protect-the-Integrity-of-Your-Encrypted-Data-by-Using-AWS-Key-Management final Map<String, String> encryptionContext = Collections.singletonMap("purpose", "test"); // Create a master key provider MasterKeyProvider<KmsMasterKey> keyProvider = KmsMasterKeyProvider.builder() .buildStrict(kmsKeyArn); // Create a cache CryptoMaterialsCache cache = new LocalCryptoMaterialsCache(cacheCapacity); // Create a caching CMM CryptoMaterialsManager cachingCmm = CachingCryptoMaterialsManager.newBuilder().withMasterKeyProvider(keyProvider) .withCache(cache) .withMaxAge(maxEntryAge, TimeUnit.SECONDS) .withMessageUseLimit(MAX_ENTRY_MSGS) .build(); // When the call to encryptData specifies a caching CMM, // the encryption operation uses the data key cache final AwsCrypto encryptionSdk = AwsCrypto.standard(); return encryptionSdk.encryptData(cachingCmm, myData, encryptionContext).getResult(); } }
- JavaScript Browser
// Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 /* This is a simple example of using a caching CMM with a KMS keyring * to encrypt and decrypt using the AWS Encryption SDK for Javascript in a browser. */ import { KmsKeyringBrowser, KMS, getClient, buildClient, CommitmentPolicy, WebCryptoCachingMaterialsManager, getLocalCryptographicMaterialsCache, } from '@aws-crypto/client-browser' import { toBase64 } from '@aws-sdk/util-base64-browser' /* This builds the client with the REQUIRE_ENCRYPT_REQUIRE_DECRYPT commitment policy, * which enforces that this client only encrypts using committing algorithm suites * and enforces that this client * will only decrypt encrypted messages * that were created with a committing algorithm suite. * This is the default commitment policy * if you build the client with `buildClient()`. */ const { encrypt, decrypt } = buildClient( CommitmentPolicy.REQUIRE_ENCRYPT_REQUIRE_DECRYPT ) /* This is injected by webpack. * The webpack.DefinePlugin or @aws-sdk/karma-credential-loader will replace the values when bundling. * The credential values are pulled from @aws-sdk/credential-provider-node * Use any method you like to get credentials into the browser. * See kms.webpack.config */ declare const credentials: { accessKeyId: string secretAccessKey: string sessionToken: string } /* This is done to facilitate testing. */ export async function testCachingCMMExample() { /* This example uses an &KMS; keyring. The generator key in a &KMS; keyring generates and encrypts the data key. * The caller needs kms:GenerateDataKey permission on the &KMS; key in generatorKeyId. */ const generatorKeyId = 'arn:aws:kms:us-west-2:658956600833:alias/EncryptDecrypt' /* Adding additional KMS keys that can decrypt. * The caller must have kms:Encrypt permission for every &KMS; key in keyIds. * You might list several keys in different AWS Regions. * This allows you to decrypt the data in any of the represented Regions. * In this example, the generator key * and the additional key are actually the same &KMS; key. * In `generatorId`, this &KMS; key is identified by its alias ARN. * In `keyIds`, this &KMS; key is identified by its key ARN. * In practice, you would specify different &KMS; keys, * or omit the `keyIds` parameter. * This is *only* to demonstrate how the &KMS; key ARNs are configured. */ const keyIds = [ 'arn:aws:kms:us-west-2:658956600833:key/b3537ef1-d8dc-4780-9f5a-55776cbb2f7f', ] /* Need a client provider that will inject correct credentials. * The credentials here are injected by webpack from your environment bundle is created * The credential values are pulled using @aws-sdk/credential-provider-node. * See kms.webpack.config * You should inject your credential into the browser in a secure manner * that works with your application. */ const { accessKeyId, secretAccessKey, sessionToken } = credentials /* getClient takes a KMS client constructor * and optional configuration values. * The credentials can be injected here, * because browsers do not have a standard credential discovery process the way Node.js does. */ const clientProvider = getClient(KMS, { credentials: { accessKeyId, secretAccessKey, sessionToken, }, }) /* You must configure the KMS keyring with your &KMS; keys */ const keyring = new KmsKeyringBrowser({ clientProvider, generatorKeyId, keyIds, }) /* Create a cache to hold the data keys (and related cryptographic material). * This example uses the local cache provided by the Encryption SDK. * The `capacity` value represents the maximum number of entries * that the cache can hold. * To make room for an additional entry, * the cache evicts the oldest cached entry. * Both encrypt and decrypt requests count independently towards this threshold. * Entries that exceed any cache threshold are actively removed from the cache. * By default, the SDK checks one item in the cache every 60 seconds (60,000 milliseconds). * To change this frequency, pass in a `proactiveFrequency` value * as the second parameter. This value is in milliseconds. */ const capacity = 100 const cache = getLocalCryptographicMaterialsCache(capacity) /* The partition name lets multiple caching CMMs share the same local cryptographic cache. * By default, the entries for each CMM are cached separately. However, if you want these CMMs to share the cache, * use the same partition name for both caching CMMs. * If you don't supply a partition name, the Encryption SDK generates a random name for each caching CMM. * As a result, sharing elements in the cache MUST be an intentional operation. */ const partition = 'local partition name' /* maxAge is the time in milliseconds that an entry will be cached. * Elements are actively removed from the cache. */ const maxAge = 1000 * 60 /* The maximum number of bytes that will be encrypted under a single data key. * This value is optional, * but you should configure the lowest practical value. */ const maxBytesEncrypted = 100 /* The maximum number of messages that will be encrypted under a single data key. * This value is optional, * but you should configure the lowest practical value. */ const maxMessagesEncrypted = 10 const cachingCMM = new WebCryptoCachingMaterialsManager({ backingMaterials: keyring, cache, partition, maxAge, maxBytesEncrypted, maxMessagesEncrypted, }) /* Encryption context is a *very* powerful tool for controlling * and managing access. * When you pass an encryption context to the encrypt function, * the encryption context is cryptographically bound to the ciphertext. * If you don't pass in the same encryption context when decrypting, * the decrypt function fails. * The encryption context is ***not*** secret! * Encrypted data is opaque. * You can use an encryption context to assert things about the encrypted data. * The encryption context helps you to determine * whether the ciphertext you retrieved is the ciphertext you expect to decrypt. * For example, if you are are only expecting data from 'us-west-2', * the appearance of a different AWS Region in the encryption context can indicate malicious interference. * See: https://docs.aws.amazon.com/encryption-sdk/latest/developer-guide/concepts.html#encryption-context * * Also, cached data keys are reused ***only*** when the encryption contexts passed into the functions are an exact case-sensitive match. * See: https://docs.aws.amazon.com/encryption-sdk/latest/developer-guide/data-caching-details.html#caching-encryption-context */ const encryptionContext = { stage: 'demo', purpose: 'simple demonstration app', origin: 'us-west-2', } /* Find data to encrypt. */ const plainText = new Uint8Array([1, 2, 3, 4, 5]) /* Encrypt the data. * The caching CMM only reuses data keys * when it know the length (or an estimate) of the plaintext. * However, in the browser, * you must provide all of the plaintext to the encrypt function. * Therefore, the encrypt function in the browser knows the length of the plaintext * and does not accept a plaintextLength option. */ const { result } = await encrypt(cachingCMM, plainText, { encryptionContext }) /* Log the plain text * only for testing and to show that it works. */ console.log('plainText:', plainText) document.write('</br>plainText:' + plainText + '</br>') /* Log the base64-encoded result * so that you can try decrypting it with another AWS Encryption SDK implementation. */ const resultBase64 = toBase64(result) console.log(resultBase64) document.write(resultBase64) /* Decrypt the data. * NOTE: This decrypt request will not use the data key * that was cached during the encrypt operation. * Data keys for encrypt and decrypt operations are cached separately. */ const { plaintext, messageHeader } = await decrypt(cachingCMM, result) /* Grab the encryption context so you can verify it. */ const { encryptionContext: decryptedContext } = messageHeader /* Verify the encryption context. * If you use an algorithm suite with signing, * the Encryption SDK adds a name-value pair to the encryption context that contains the public key. * Because the encryption context might contain additional key-value pairs, * do not include a test that requires that all key-value pairs match. * Instead, verify that the key-value pairs that you supplied to the `encrypt` function are included in the encryption context that the `decrypt` function returns. */ Object.entries(encryptionContext).forEach(([key, value]) => { if (decryptedContext[key] !== value) throw new Error('Encryption Context does not match expected values') }) /* Log the clear message * only for testing and to show that it works. */ document.write('</br>Decrypted:' + plaintext) console.log(plaintext) /* Return the values to make testing easy. */ return { plainText, plaintext } }
- JavaScript Node.js
-
// Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 import { KmsKeyringNode, buildClient, CommitmentPolicy, NodeCachingMaterialsManager, getLocalCryptographicMaterialsCache, } from '@aws-crypto/client-node' /* This builds the client with the REQUIRE_ENCRYPT_REQUIRE_DECRYPT commitment policy, * which enforces that this client only encrypts using committing algorithm suites * and enforces that this client * will only decrypt encrypted messages * that were created with a committing algorithm suite. * This is the default commitment policy * if you build the client with `buildClient()`. */ const { encrypt, decrypt } = buildClient( CommitmentPolicy.REQUIRE_ENCRYPT_REQUIRE_DECRYPT ) export async function cachingCMMNodeSimpleTest() { /* An &KMS; key is required to generate the data key. * You need kms:GenerateDataKey permission on the &KMS; key in generatorKeyId. */ const generatorKeyId = 'arn:aws:kms:us-west-2:658956600833:alias/EncryptDecrypt' /* Adding alternate &KMS; keys that can decrypt. * Access to kms:Encrypt is required for every &KMS; key in keyIds. * You might list several keys in different AWS Regions. * This allows you to decrypt the data in any of the represented Regions. * In this example, the generator key * and the additional key are actually the same &KMS; key. * In `generatorId`, this &KMS; key is identified by its alias ARN. * In `keyIds`, this &KMS; key is identified by its key ARN. * In practice, you would specify different &KMS; keys, * or omit the `keyIds` parameter. * This is *only* to demonstrate how the &KMS; key ARNs are configured. */ const keyIds = [ 'arn:aws:kms:us-west-2:658956600833:key/b3537ef1-d8dc-4780-9f5a-55776cbb2f7f', ] /* The &KMS; keyring must be configured with the desired &KMS; keys * This example passes the keyring to the caching CMM * instead of using it directly. */ const keyring = new KmsKeyringNode({ generatorKeyId, keyIds }) /* Create a cache to hold the data keys (and related cryptographic material). * This example uses the local cache provided by the Encryption SDK. * The `capacity` value represents the maximum number of entries * that the cache can hold. * To make room for an additional entry, * the cache evicts the oldest cached entry. * Both encrypt and decrypt requests count independently towards this threshold. * Entries that exceed any cache threshold are actively removed from the cache. * By default, the SDK checks one item in the cache every 60 seconds (60,000 milliseconds). * To change this frequency, pass in a `proactiveFrequency` value * as the second parameter. This value is in milliseconds. */ const capacity = 100 const cache = getLocalCryptographicMaterialsCache(capacity) /* The partition name lets multiple caching CMMs share the same local cryptographic cache. * By default, the entries for each CMM are cached separately. However, if you want these CMMs to share the cache, * use the same partition name for both caching CMMs. * If you don't supply a partition name, the Encryption SDK generates a random name for each caching CMM. * As a result, sharing elements in the cache MUST be an intentional operation. */ const partition = 'local partition name' /* maxAge is the time in milliseconds that an entry will be cached. * Elements are actively removed from the cache. */ const maxAge = 1000 * 60 /* The maximum amount of bytes that will be encrypted under a single data key. * This value is optional, * but you should configure the lowest value possible. */ const maxBytesEncrypted = 100 /* The maximum number of messages that will be encrypted under a single data key. * This value is optional, * but you should configure the lowest value possible. */ const maxMessagesEncrypted = 10 const cachingCMM = new NodeCachingMaterialsManager({ backingMaterials: keyring, cache, partition, maxAge, maxBytesEncrypted, maxMessagesEncrypted, }) /* Encryption context is a *very* powerful tool for controlling * and managing access. * When you pass an encryption context to the encrypt function, * the encryption context is cryptographically bound to the ciphertext. * If you don't pass in the same encryption context when decrypting, * the decrypt function fails. * The encryption context is ***not*** secret! * Encrypted data is opaque. * You can use an encryption context to assert things about the encrypted data. * The encryption context helps you to determine * whether the ciphertext you retrieved is the ciphertext you expect to decrypt. * For example, if you are are only expecting data from 'us-west-2', * the appearance of a different AWS Region in the encryption context can indicate malicious interference. * See: https://docs.aws.amazon.com/encryption-sdk/latest/developer-guide/concepts.html#encryption-context * * Also, cached data keys are reused ***only*** when the encryption contexts passed into the functions are an exact case-sensitive match. * See: https://docs.aws.amazon.com/encryption-sdk/latest/developer-guide/data-caching-details.html#caching-encryption-context */ const encryptionContext = { stage: 'demo', purpose: 'simple demonstration app', origin: 'us-west-2', } /* Find data to encrypt. A simple string. */ const cleartext = 'asdf' /* Encrypt the data. * The caching CMM only reuses data keys * when it know the length (or an estimate) of the plaintext. * If you do not know the length, * because the data is a stream * provide an estimate of the largest expected value. * * If your estimate is smaller than the actual plaintext length * the AWS Encryption SDK will throw an exception. * * If the plaintext is not a stream, * the AWS Encryption SDK uses the actual plaintext length * instead of any length you provide. */ const { result } = await encrypt(cachingCMM, cleartext, { encryptionContext, plaintextLength: 4, }) /* Decrypt the data. * NOTE: This decrypt request will not use the data key * that was cached during the encrypt operation. * Data keys for encrypt and decrypt operations are cached separately. */ const { plaintext, messageHeader } = await decrypt(cachingCMM, result) /* Grab the encryption context so you can verify it. */ const { encryptionContext: decryptedContext } = messageHeader /* Verify the encryption context. * If you use an algorithm suite with signing, * the Encryption SDK adds a name-value pair to the encryption context that contains the public key. * Because the encryption context might contain additional key-value pairs, * do not include a test that requires that all key-value pairs match. * Instead, verify that the key-value pairs that you supplied to the `encrypt` function are included in the encryption context that the `decrypt` function returns. */ Object.entries(encryptionContext).forEach(([key, value]) => { if (decryptedContext[key] !== value) throw new Error('Encryption Context does not match expected values') }) /* Return the values so the code can be tested. */ return { plaintext, result, cleartext, messageHeader } }
- Python
-
# Copyright 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"). You # may not use this file except in compliance with the License. A copy of # the License is located at # # http://aws.amazon.com/apache2.0/ # # or in the "license" file accompanying this file. This file is # distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF # ANY KIND, either express or implied. See the License for the specific # language governing permissions and limitations under the License. """Example of encryption with data key caching.""" import aws_encryption_sdk from aws_encryption_sdk import CommitmentPolicy def encrypt_with_caching(kms_key_arn, max_age_in_cache, cache_capacity): """Encrypts a string using an &KMS; key and data key caching. :param str kms_key_arn: Amazon Resource Name (ARN) of the &KMS; key :param float max_age_in_cache: Maximum time in seconds that a cached entry can be used :param int cache_capacity: Maximum number of entries to retain in cache at once """ # Data to be encrypted my_data = "My plaintext data" # Security thresholds # Max messages (or max bytes per) data key are optional MAX_ENTRY_MESSAGES = 100 # Create an encryption context encryption_context = {"purpose": "test"} # Set up an encryption client with an explicit commitment policy. Note that if you do not explicitly choose a # commitment policy, REQUIRE_ENCRYPT_REQUIRE_DECRYPT is used by default. client = aws_encryption_sdk.EncryptionSDKClient(commitment_policy=CommitmentPolicy.REQUIRE_ENCRYPT_REQUIRE_DECRYPT) # Create a master key provider for the &KMS; key key_provider = aws_encryption_sdk.StrictAwsKmsMasterKeyProvider(key_ids=[kms_key_arn]) # Create a local cache cache = aws_encryption_sdk.LocalCryptoMaterialsCache(cache_capacity) # Create a caching CMM caching_cmm = aws_encryption_sdk.CachingCryptoMaterialsManager( master_key_provider=key_provider, cache=cache, max_age=max_age_in_cache, max_messages_encrypted=MAX_ENTRY_MESSAGES, ) # When the call to encrypt data specifies a caching CMM, # the encryption operation uses the data key cache specified # in the caching CMM encrypted_message, _header = client.encrypt( source=my_data, materials_manager=caching_cmm, encryption_context=encryption_context ) return encrypted_message