@@ -101,7 +101,6 @@ Please avoid using these and instead use components in the MPL.
101
101
Master Key Providers
102
102
--------------------
103
103
Master key providers are resources that provide master keys.
104
- An example of a master key provider is `AWS KMS `_.
105
104
106
105
To encrypt data in this client, a ``MasterKeyProvider `` object must contain at least one ``MasterKey `` object.
107
106
@@ -115,7 +114,7 @@ Please install this library and migrate master key providers to keyring interfac
115
114
Master Keys
116
115
-----------
117
116
Master keys generate, encrypt, and decrypt data keys.
118
- An example of a master key is a ` KMS customer master key (CMK) `_.
117
+ An example of a master key is an ` AWS KMS key `_.
119
118
120
119
NOTE: Master keys are deprecated
121
120
and have been superseded by keyrings
@@ -154,13 +153,13 @@ Note: You must also install the `AWS Cryptographic Material Providers Library (M
154
153
155
154
AwsKmsKeyring
156
155
=============================
157
- A ``AwsKmsKeyring `` is configured with an AWS KMS key ARN whose AWS KMS key
156
+ An ``AwsKmsKeyring `` is configured with an AWS KMS key ARN whose AWS KMS key
158
157
will be used to generate, encrypt, and decrypt data keys.
159
158
On encryption, it encrypts the plaintext with the data key.
160
159
On decryption, it decrypts an encrypted version of the data key,
161
160
then uses the decrypted data key to decrypt the ciphertext.
162
161
163
- To create a ``AwsKmsKeyring `` you must provide a AWS KMS key ARN.
162
+ To create an ``AwsKmsKeyring `` you must provide a AWS KMS key ARN.
164
163
For keyrings that will only be used for encryption,
165
164
you can use any valid `KMS key identifier `_.
166
165
For providers that will be used for decryption,
@@ -174,46 +173,209 @@ pre-existing instance of a ``botocore session`` to the ``AwsKmsKeyring``.
174
173
This latter option can be useful if you have an alternate way to store your AWS credentials or
175
174
you want to reuse an existing instance of a botocore session in order to decrease startup costs.
176
175
177
- TODO-MPL: Code example
176
+ .. code :: python
177
+
178
+ import boto3
179
+ from aws_cryptographic_materialproviders.mpl import AwsCryptographicMaterialProviders
180
+ from aws_cryptographic_materialproviders.mpl.config import MaterialProvidersConfig
181
+ from aws_cryptographic_materialproviders.mpl.models import CreateAwsKmsKeyringInput
182
+ from aws_cryptographic_materialproviders.mpl.references import IKeyring
183
+
184
+ import aws_encryption_sdk
185
+ from aws_encryption_sdk import CommitmentPolicy
186
+
187
+ # Instantiate the encryption SDK client.
188
+ client = aws_encryption_sdk.EncryptionSDKClient(
189
+ commitment_policy = CommitmentPolicy.REQUIRE_ENCRYPT_REQUIRE_DECRYPT
190
+ )
191
+
192
+ # Create a KMS keyring.
193
+ mat_prov: AwsCryptographicMaterialProviders = AwsCryptographicMaterialProviders(
194
+ config = MaterialProvidersConfig()
195
+ )
196
+
197
+ keyring_input: CreateAwsKmsKeyringInput = CreateAwsKmsKeyringInput(
198
+ kms_key_id = ' arn:aws:kms:us-east-1:2222222222222:key/22222222-2222-2222-2222-222222222222' ,
199
+ kms_client = boto3.client(' kms' , region_name = " us-east-1" )
200
+ )
201
+
202
+ kms_keyring: IKeyring = mat_prov.create_aws_kms_keyring(
203
+ input = keyring_input
204
+ )
205
+
178
206
179
207
If you want to configure a keyring with multiple AWS KMS keys, see the multi-keyring.
180
208
181
209
MultiKeyring
182
210
============
183
211
184
- A ``MultiKeyring `` is configured with an optional generator keyring and a list of child keyrings.
212
+ A ``MultiKeyring `` is configured with an optional generator keyring and a list of
213
+ child keyrings of the same or a different type.
214
+
215
+ The effect is like using several keyrings in a series. When you use a multi-keyring to
216
+ encrypt data, any of the wrapping keys in any of its keyrings can decrypt that data.
185
217
186
- TODO-MPL: More words
218
+ .. code :: python
219
+
220
+ import boto3
221
+ from aws_cryptographic_materialproviders.mpl import AwsCryptographicMaterialProviders
222
+ from aws_cryptographic_materialproviders.mpl.config import MaterialProvidersConfig
223
+ from aws_cryptographic_materialproviders.mpl.models import CreateAwsKmsMultiKeyringInput
224
+ from aws_cryptographic_materialproviders.mpl.references import IKeyring
225
+
226
+ import aws_encryption_sdk
227
+ from aws_encryption_sdk import CommitmentPolicy
228
+
229
+ # Instantiate the encryption SDK client.
230
+ client = aws_encryption_sdk.EncryptionSDKClient(
231
+ commitment_policy = CommitmentPolicy.REQUIRE_ENCRYPT_REQUIRE_DECRYPT
232
+ )
233
+
234
+ # Create an AwsKmsMultiKeyring that protects your data under two different KMS Keys.
235
+ # Either KMS Key individually is capable of decrypting data encrypted under this Multi Keyring.
236
+ mat_prov: AwsCryptographicMaterialProviders = AwsCryptographicMaterialProviders(
237
+ config = MaterialProvidersConfig()
238
+ )
239
+
240
+ kms_multi_keyring_input: CreateAwsKmsMultiKeyringInput = CreateAwsKmsMultiKeyringInput(
241
+ generator = ' arn:aws:kms:us-east-1:2222222222222:key/22222222-2222-2222-2222-222222222222' ,
242
+ kms_key_ids = [' arn:aws:kms:us-east-1:3333333333333:key/33333333-3333-3333-3333-333333333333' ]
243
+ )
244
+
245
+ kms_multi_keyring: IKeyring = mat_prov.create_aws_kms_multi_keyring(
246
+ input = kms_multi_keyring_input
247
+ )
187
248
188
- TODO-MPL: Code example
189
249
190
250
AwsKmsDiscoveryKeyring
191
251
======================
192
252
We recommend using an ``AwsKmsKeyring `` in order to ensure that you can only
193
253
encrypt and decrypt data using the AWS KMS key ARN you expect,
194
254
or a ``MultiKeyring `` if you are using multiple keys. However, if you are unable to
195
255
explicitly identify the AWS KMS key ARNs that should be used for decryption, you can instead
196
- use a ``AwsKmsDiscoveryKeyring `` for decryption operations. This provider
256
+ use an ``AwsKmsDiscoveryKeyring `` for decryption operations. This provider
197
257
attempts decryption of any ciphertexts as long as they match a ``DiscoveryFilter `` that
198
258
you configure. A ``DiscoveryFilter `` consists of a list of AWS account ids and an AWS
199
259
partition.
200
260
201
- TODO-MPL: Code example
261
+ .. code :: python
262
+
263
+ import boto3
264
+ from aws_cryptographic_materialproviders.mpl import AwsCryptographicMaterialProviders
265
+ from aws_cryptographic_materialproviders.mpl.config import MaterialProvidersConfig
266
+ ffrom aws_cryptographic_materialproviders.mpl.models import (
267
+ CreateAwsKmsDiscoveryKeyringInput,
268
+ DiscoveryFilter,
269
+ )
270
+ from aws_cryptographic_materialproviders.mpl.references import IKeyring
271
+
272
+ import aws_encryption_sdk
273
+ from aws_encryption_sdk import CommitmentPolicy
274
+
275
+ # Instantiate the encryption SDK client.
276
+ client = aws_encryption_sdk.EncryptionSDKClient(
277
+ commitment_policy = CommitmentPolicy.REQUIRE_ENCRYPT_REQUIRE_DECRYPT
278
+ )
279
+
280
+ # Create a Discovery keyring to use for decryption
281
+ mat_prov: AwsCryptographicMaterialProviders = AwsCryptographicMaterialProviders(
282
+ config = MaterialProvidersConfig()
283
+ )
284
+
285
+ discovery_keyring_input: CreateAwsKmsDiscoveryKeyringInput = CreateAwsKmsDiscoveryKeyringInput(
286
+ kms_client = boto3.client(' kms' , region_name = " us-east-1" ),
287
+ discovery_filter = DiscoveryFilter(
288
+ account_ids = [" 2222222222222" ],
289
+ partition = " aws"
290
+ )
291
+ )
292
+
293
+ discovery_keyring: IKeyring = mat_prov.create_aws_kms_discovery_keyring(
294
+ input = discovery_keyring_input
295
+ )
296
+
202
297
203
298
If you do not want to filter the set of allowed accounts, you can also omit the ``discovery_filter `` argument.
204
299
205
- Note that a ``AwsKmsDiscoveryKeyring `` cannot be used for encryption operations.
300
+ Note that an ``AwsKmsDiscoveryKeyring `` cannot be used for encryption operations.
206
301
207
302
Encryption and Decryption
208
303
=========================
209
304
After you create an instance of an ``EncryptionSDKClient `` and a ``Keyring ``, you can use either of
210
305
the client's two ``encrypt ``/``decrypt `` functions to encrypt and decrypt your data.
211
306
212
- TODO-MPL: Code example; basic example with keyring
307
+ Here's an example for using a KMS keyring for encryption and decryption:
308
+
309
+ .. code :: python
310
+
311
+ # Encrypt the data.
312
+ my_ciphertext, enc_header = client.encrypt(
313
+ source = my_plaintext,
314
+ keyring = kms_keyring
315
+ )
316
+
317
+ # Decrypt your encrypted data.
318
+ my_decrypted_plaintext, dec_header = client.decrypt(
319
+ source = my_ciphertext,
320
+ keyring = kms_keyring
321
+ )
213
322
214
323
You can provide an `encryption context `_: a form of additional authenticating information.
215
324
216
- TODO-MPL: Code example with encryption context
325
+ Here's an example for using KMS keyring with an encryption context:
326
+
327
+ .. code :: python
328
+
329
+ import boto3
330
+ from aws_cryptographic_materialproviders.mpl import AwsCryptographicMaterialProviders
331
+ from aws_cryptographic_materialproviders.mpl.config import MaterialProvidersConfig
332
+ from aws_cryptographic_materialproviders.mpl.models import CreateAwsKmsKeyringInput
333
+ from aws_cryptographic_materialproviders.mpl.references import IKeyring
334
+
335
+ import aws_encryption_sdk
336
+ from aws_encryption_sdk import CommitmentPolicy
337
+
338
+ # Instantiate the encryption SDK client.
339
+ client = aws_encryption_sdk.EncryptionSDKClient(
340
+ commitment_policy = CommitmentPolicy.REQUIRE_ENCRYPT_REQUIRE_DECRYPT
341
+ )
342
+
343
+ # Create an encryption context
344
+ encryption_context: Dict[str , str ] = {
345
+ " encryption" : " context" ,
346
+ " is not" : " secret" ,
347
+ " but adds" : " useful metadata" ,
348
+ " that can help you" : " be confident that" ,
349
+ " the data you are handling" : " is what you think it is" ,
350
+ }
351
+
352
+ # Create a KMS keyring.
353
+ mat_prov: AwsCryptographicMaterialProviders = AwsCryptographicMaterialProviders(
354
+ config = MaterialProvidersConfig()
355
+ )
356
+
357
+ keyring_input: CreateAwsKmsKeyringInput = CreateAwsKmsKeyringInput(
358
+ kms_key_id = ' arn:aws:kms:us-east-1:2222222222222:key/22222222-2222-2222-2222-222222222222' ,
359
+ kms_client = boto3.client(' kms' , region_name = " us-east-1" )
360
+ )
361
+
362
+ kms_keyring: IKeyring = mat_prov.create_aws_kms_keyring(
363
+ input = keyring_input
364
+ )
365
+
366
+ # Encrypt the data with the encryptionContext.
367
+ my_ciphertext, enc_header = client.encrypt(
368
+ source = my_plaintext,
369
+ keyring = kms_keyring,
370
+ encryption_context = encryption_context
371
+ )
372
+
373
+ # Decrypt your encrypted data.
374
+ my_decrypted_plaintext, dec_header = client.decrypt(
375
+ source = my_ciphertext,
376
+ keyring = kms_keyring
377
+ )
378
+
217
379
218
380
Streaming
219
381
=========
@@ -222,50 +384,67 @@ memory at once, you can use this library's streaming clients directly. The strea
222
384
file-like objects, and behave exactly as you would expect a Python file object to behave,
223
385
offering context manager and iteration support.
224
386
225
- TODO-MPL: Update code example to use a keyring
226
-
227
387
.. code :: python
228
388
389
+ import boto3
390
+ from aws_cryptographic_materialproviders.mpl import AwsCryptographicMaterialProviders
391
+ from aws_cryptographic_materialproviders.mpl.config import MaterialProvidersConfig
392
+ from aws_cryptographic_materialproviders.mpl.models import CreateAwsKmsKeyringInput
393
+ from aws_cryptographic_materialproviders.mpl.references import IKeyring
394
+
229
395
import aws_encryption_sdk
230
- from aws_encryption_sdk.identifiers import CommitmentPolicy
231
- import filecmp
396
+ from aws_encryption_sdk import CommitmentPolicy
232
397
398
+ # Instantiate the encryption SDK client.
233
399
client = aws_encryption_sdk.EncryptionSDKClient(
234
- commitment_policy = CommitmentPolicy.FORBID_ENCRYPT_ALLOW_DECRYPT
400
+ commitment_policy = CommitmentPolicy.REQUIRE_ENCRYPT_ALLOW_DECRYPT
401
+ )
402
+
403
+ # Create a keyring.
404
+ mat_prov: AwsCryptographicMaterialProviders = AwsCryptographicMaterialProviders(
405
+ config = MaterialProvidersConfig()
406
+ )
407
+
408
+ keyring_input: CreateAwsKmsKeyringInput = CreateAwsKmsKeyringInput(
409
+ kms_key_id = ' arn:aws:kms:us-east-1:2222222222222:key/22222222-2222-2222-2222-222222222222' ,
410
+ kms_client = boto3.client(' kms' , region_name = " us-east-1" )
411
+ )
412
+
413
+ kms_keyring: IKeyring = mat_prov.create_aws_kms_keyring(
414
+ input = keyring_input
235
415
)
236
416
237
- # TODO -MPL: create a keyring
238
417
plaintext_filename = ' my-secret-data.dat'
239
418
ciphertext_filename = ' my-encrypted-data.ct'
240
419
420
+ # Encrypt the data stream.
241
421
with open (plaintext_filename, ' rb' ) as pt_file, open (ciphertext_filename, ' wb' ) as ct_file:
242
422
with client.stream(
243
423
mode = ' e' ,
244
424
source = pt_file,
245
- keyring = # TODO -MPL: provide keyring
425
+ keyring = kms_keyring
246
426
) as encryptor:
247
427
for chunk in encryptor:
248
428
ct_file.write(chunk)
249
429
250
430
decrypted_filename = ' my-decrypted-data.dat'
251
431
432
+ # Decrypt your encrypted data stream.
252
433
with open (ciphertext_filename, ' rb' ) as ct_file, open (decrypted_filename, ' wb' ) as pt_file:
253
434
with client.stream(
254
435
mode = ' d' ,
255
436
source = ct_file,
256
- keyring = # TODO -MPL: provide keyring
437
+ keyring = kms_keyring
257
438
) as decryptor:
258
439
for chunk in decryptor:
259
440
pt_file.write(chunk)
260
441
261
- assert filecmp.cmp(plaintext_filename, decrypted_filename)
262
- assert encryptor.header.encryption_context == decryptor.header.encryption_context
263
442
264
443
Performance Considerations
265
444
==========================
266
445
Adjusting the frame size can significantly improve the performance of encrypt/decrypt operations with this library.
267
446
268
- Processing each frame in a framed message involves a certain amount of overhead. If you are encrypting a large file,
447
+ Processing each frame in a framed message involves a certain amount of overhead. If you are encrypting a large file,
269
448
increasing the frame size can offer potentially significant performance gains. We recommend that you tune these values
270
449
to your use-case in order to obtain peak performance.
271
450
@@ -297,7 +476,7 @@ sharing entries in that cache across threads needs to be done carefully
297
476
.. _Read the Docs : http://aws-encryption-sdk-python.readthedocs.io/en/latest/
298
477
.. _GitHub : https://github.com/aws/aws-encryption-sdk-python/
299
478
.. _AWS KMS : https://docs.aws.amazon.com/kms/latest/developerguide/overview.html
300
- .. _ KMS customer master key (CMK) : https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#master_keys
479
+ .. _ AWS KMS key : https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#master_keys
301
480
.. _KMS key identifier : https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#key-id
302
481
.. _boto3 SDK : https://boto3.readthedocs.io/en/latest/
303
482
.. _standard means by which boto3 locates credentials : https://boto3.readthedocs.io/en/latest/guide/configuration.html
0 commit comments