Skip to content

Commit a722dd3

Browse files
doc(examples): Add example README
1 parent fb379d4 commit a722dd3

File tree

4 files changed

+182
-93
lines changed

4 files changed

+182
-93
lines changed

README.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,12 @@ Run the test vector suite after [set up](testVector/README.md) with:
5757
dotnet test testVectors
5858
```
5959

60+
Run tests on examples, to ensure they are up to date:
61+
62+
```
63+
dotnet test examples/dotnet
64+
```
65+
6066
Please note that tests and test vectors require internet access and valid AWS credentials, since calls to KMS are made as part of the test workflow.
6167

6268
## License

examples/dotnet/README.md

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
# AWS Encryption SDK for .NET Examples
2+
3+
This section features examples that show you
4+
how to use the AWS Encryption SDK.
5+
We demonstrate how to use the encryption and decryption APIs
6+
and how to set up some common configuration patterns.
7+
8+
## APIs
9+
10+
The AWS Encryption SDK provides two high-level APIs:
11+
one-step APIs that process the entire operation in memory
12+
and streaming APIs.
13+
14+
You can find examples that demonstrate these APIs
15+
in the [`examples/dotnet/`](./) directory.
16+
17+
* [How to encrypt and decrypt](./) *TODO*
18+
* [How to change the algorithm suite](./) *TODO*
19+
* [How to encrypt and decrypt data streams in memory](./) *TODO*
20+
* [How to encrypt and decrypt data streamed between files](./) *TODO*
21+
22+
## Configuration
23+
24+
To use the encryption and decryption APIs,
25+
you need to describe how you want the library to protect your data keys.
26+
You can do this by configuring
27+
[keyrings](#keyrings) or [cryptographic materials managers](#cryptographic-materials-managers).
28+
These examples will show you how to use the configuration tools that we include for you
29+
and how to create some of your own.
30+
We start with AWS KMS examples, then show how to use other wrapping keys.
31+
32+
* Using AWS Key Management Service (AWS KMS) Keyring
33+
* [How to use one AWS KMS CMK](./) *TODO*
34+
* [How to use multiple AWS KMS CMKs in different regions](./) *TODO*
35+
* [How to decrypt when you don't know the CMK](./) *TODO*
36+
* [How to decrypt within a region](./) *TODO*
37+
* [How to decrypt with a preferred region but failover to others](./) *TODO*
38+
* [How to reproduce the behavior of an AWS KMS master key provider](./) *TODO*
39+
* Using raw wrapping keys
40+
* [How to use a raw AES wrapping key](./keyrings/RawRSAKeyring/RawAESKeyringExample.cs)
41+
* [How to use a raw RSA wrapping key](./) *TODO*
42+
* [How to use a raw RSA wrapping key when the key is PEM or DER encoded](./) *TODO*
43+
* [How to encrypt with a raw RSA public key wrapping key without access to the private key](./) *TODO*
44+
* Combining wrapping keys
45+
* [How to combine AWS KMS with an offline escrow key](./) *TODO*
46+
* How to reuse data keys across multiple messages
47+
* [with the caching cryptographic materials manager](./) *TODO*
48+
* How to restrict algorithm suites
49+
* [with a custom cryptographic materials manager](./) *TODO*
50+
* How to require encryption context fields
51+
* [with a custom cryptographic materials manager](./) *TODO*
52+
53+
### Keyrings
54+
55+
Keyrings are the most common way for you to configure the AWS Encryption SDK.
56+
They determine how the AWS Encryption SDK protects your data.
57+
You can find these examples in [`examples/dotnet/keyrings`](./keyring).
58+
59+
### Cryptographic Materials Managers
60+
61+
Keyrings define how your data keys are protected,
62+
but there is more going on here than just protecting data keys.
63+
64+
Cryptographic materials managers give you higher-level controls
65+
over how the AWS Encryption SDK protects your data.
66+
This can include things like
67+
enforcing the use of certain algorithm suites or encryption context settings,
68+
reusing data keys across messages,
69+
or changing how you interact with keyrings.
70+
You can find these examples in
71+
[`examples/dotnet/CryptoMaterialsManager`](./CryptoMaterialsManager).
72+
73+
# Writing Examples
74+
75+
If you want to contribute a new example, that's awesome!
76+
To make sure that your example is tested in our CI,
77+
please make sure that it meets the following requirements:
78+
79+
1. The example MUST be a distinct module in the [`examples/dotnet/`](./) directory.
80+
1. The example MAY be nested arbitrarily deeply.
81+
1. Each example file MUST contain exactly one example.
82+
1. Each example filename MUST be descriptive.
83+
1. Each example file MUST contain a public class matching the filename.
84+
1. Each example file MUST contain a method called `run` that runs the example.
85+
1. Each example MUST be exercised by a `[Fact]` test method within its class.

examples/dotnet/RawAESKeyring/RawAESKeyringExample.cs

Lines changed: 0 additions & 93 deletions
This file was deleted.
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
// This example shows how to configure and use a raw AES keyring.
2+
//
3+
// https://docs.aws.amazon.com/encryption-sdk/latest/developer-guide/choose-keyring.html#use-raw-aes-keyring
4+
//
5+
// In this example, we use the encrypt and decrypt APIs.
6+
using System;
7+
using System.Collections.Generic;
8+
using System.IO;
9+
using System.Text;
10+
11+
using AWSEncryptionSDK;
12+
using KeyringDefs;
13+
using RawAESKeyringDef;
14+
15+
using Org.BouncyCastle.Security; // In this example, we use BouncyCastle to generate a wrapping key.
16+
17+
using ExampleUtils;
18+
using Xunit;
19+
20+
/// Demonstrate an encrypt/decrypt cycle using a raw AES keyring.
21+
public class RawAESKeyringExample {
22+
static void Run(MemoryStream plaintext) {
23+
24+
// Create your encryption context.
25+
// Remember that your encryption context is NOT SECRET.
26+
// https://docs.aws.amazon.com/encryption-sdk/latest/developer-guide/concepts.html#encryption-context
27+
IDictionary<string, string> encryptionContext = new Dictionary<string, string>() {
28+
{"encryption", "context"},
29+
{"is not", "secret"},
30+
{"but adds", "useful metadata"},
31+
{"that can help you", "be confident that"},
32+
{"the data you are handling", "is what you think it is"}
33+
};
34+
35+
// Generate a 256-bit AES key to use with your keyring.
36+
// Here we use BouncyCastle, but you don't have to.
37+
//
38+
// In practice, you should get this key from a secure key management system such as an HSM.
39+
byte[] key = GeneratorUtilities.GetKeyGenerator("AES256").GenerateKey();
40+
41+
// The key namespace and key name are defined by you
42+
// and are used by the raw AES keyring to determine
43+
// whether it should attempt to decrypt an encrypted data key.
44+
//
45+
// https://docs.aws.amazon.com/encryption-sdk/latest/developer-guide/choose-keyring.html#use-raw-aes-keyring
46+
byte[] keyName = Encoding.UTF8.GetBytes("My 256-bit AES wrapping key");
47+
byte[] keyNamespace = Encoding.UTF8.GetBytes("Some managed raw keys");
48+
49+
// Create the keyring that determines how your data keys are protected.
50+
RawAESKeyring keyring = AWSEncryptionSDK.Keyrings.MakeRawAESKeyring(
51+
keyNamespace,
52+
keyName,
53+
key,
54+
DafnyFFI.AESWrappingAlgorithm.AES_GCM_256
55+
);
56+
57+
// Encrypt your plaintext data.
58+
MemoryStream ciphertext = AWSEncryptionSDK.Client.Encrypt(new AWSEncryptionSDK.Client.EncryptRequest{
59+
plaintext = plaintext,
60+
keyring = keyring,
61+
encryptionContext = encryptionContext
62+
});
63+
64+
// Demonstrate that the ciphertext and plaintext are different.
65+
Assert.NotEqual(ciphertext.ToArray(), plaintext.ToArray());
66+
67+
// Decrypt your encrypted data using the same keyring you used on encrypt.
68+
//
69+
// You do not need to specify the encryption context on decrypt
70+
// because the header of the encrypted message includes the encryption context.
71+
MemoryStream decrypted = AWSEncryptionSDK.Client.Decrypt(new AWSEncryptionSDK.Client.DecryptRequest{
72+
message = ciphertext,
73+
keyring = keyring
74+
});
75+
76+
// Demonstrate that the decrypted plaintext is identical to the original plaintext.
77+
Assert.Equal(decrypted.ToArray(), plaintext.ToArray());
78+
// Verify that the encryption context used in the decrypt operation includes
79+
// the encryption context that you specified when encrypting.
80+
// The AWS Encryption SDK can add pairs, so don't require an exact match.
81+
//
82+
// In production, always use a meaningful encryption context.
83+
// TODO: Add logic that checks the encryption context.
84+
}
85+
86+
// We test examples to ensure they remain up-to-date.
87+
[Fact]
88+
public void TestRawAESKeyringExample() {
89+
Run(ExampleUtils.ExampleUtils.GetPlaintextStream());
90+
}
91+
}

0 commit comments

Comments
 (0)