Skip to content

Additional example code for Keyrings #155

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Feb 12, 2020
Merged

Conversation

WesleyRosenblum
Copy link
Contributor

Description of changes:

Adding example code for Keyrings, as well as updating and adding the data key caching example code from the Documentation.

By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.

Check any applicable:

  • Were any files moved? Moving files changes their URL, which breaks all hyperlinks to the files.

@mattsb42-aws mattsb42-aws mentioned this pull request Feb 5, 2020
15 tasks
Copy link
Contributor

@juneb juneb left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not finished. I'll finish tomorrow.

* In practice, this key would be saved in a secure location.
* For this demo, we generate a new random key for each operation.
*/
private static SecretKey retrieveEncryptionKey() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since you're not retrieving anything from anywhere, I would call this generateEncryptKey. Do we need a warning that this is just a proof of concept or is this really a good, secure way to generate a key? If it is, I would say so.

Copy link
Contributor Author

@WesleyRosenblum WesleyRosenblum Feb 6, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

according to the Java documentation it is a "cryptographically strong random number generator." so it should be fine but I'm not sure about what wording would make sense here. We could also generate a key in this manner:

KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");
keyGenerator.init(128);
return keyGenerator.generateKey();

I'm not sure if that is preferable, @SalusaSecondus do you have thoughts?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Both SecureRandom and KeyGenerator are generally equally good for AES keys. I think that I see SecureRandom slightly more commonly.

.keyring(keyring)
.ciphertext(ciphertext).build());

// 7. Before verifying the plaintext, verify that the key that was used in the encryption
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// 7. Before verifying the plaintext, verify that the key that was used in the encryption
// 7. Before returning the plaintext, verify that the same encryption key was used in the encryption and decryption operations.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the encryption key isn't the same, the decrypt fails. I think what we're testing here is that the AES key that we're using is the one that we expect. But the namespace and name are arbitrary, so you can spoof the namespace/name.

We need to explain this more clearly.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This language was adapted from the original BasicEncryptionExample that was using a KmsMasterKeyProvider. I think this verification doesn't make sense for the RawAES key, so I've removed this step. For the AwsKmsKeyring, the Keyring will only use the configured CMKs for decryption (which is different than the KmsMasterKeyProvider) so I'll update the current BasicEncryptionExample with new language related to that

@WesleyRosenblum WesleyRosenblum force-pushed the examplecode branch 2 times, most recently from c798b6e to 0bd2587 Compare February 7, 2020 19:06
Copy link
Contributor

@SalusaSecondus SalusaSecondus left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

// 7. Verify that the encryption context in the result contains the
// data that we expect. The SDK can add values to the encryption context,
// so there may be additional keys in the result context.
assert decryptResult.getEncryptionContext().get("ExampleContextKey").equals("ExampleContextValue");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Who is "we?"

To verify that the encryption context used to decrypt the data was the encryption context you expected, use the keyring trace. This helps to ensure that you decrypted the ciphertext that you intended.

When verifying, test that your expected encryption context is a subset of the actual encryption context, not an exact match. The Encryption SDK adds the signing key to the encryption context when appropriate.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think you intended to mention the keyring trace here, I went with:

To verify that the encryption context used to decrypt the data was the encryption context you expected, examine the encryption context in the result. This helps to ensure that you decrypted the ciphertext that you intended.

.generatorKeyId(AwsKmsCmkId.fromString(kmsAliasName)).build());
}

// Collect keyrings into single multi keyring and add cache. The keyring for the
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

s/multi keyring/multi-keyring

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We've instantiated only one keyring (line 75). Where do the keyrings in the childrenKeyrings keyring list come from? (Sorry if that's a dumb q.)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's instantiating a new Aws Kms Keyring for each iteration of the loop and adding it the list of keyrings.

}

// Collect keyrings into single multi keyring and add cache. The keyring for the
// first region will be used to generate a data key.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need to fix this sentence. It sounds like a rule; not an artifact of this particular code. The generatorKeyring is defined as a multiKeyring property.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated

.withRegion(region.getName())
.build());

keyrings.add(StandardKeyrings.awsKms()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe a comment:
Create a KMS keyring with one CMK that is the generator key.

@ttjsu-aws ttjsu-aws mentioned this pull request Feb 11, 2020
15 tasks
@WesleyRosenblum WesleyRosenblum merged commit 12f0c42 into materialsmanager Feb 12, 2020
@WesleyRosenblum WesleyRosenblum deleted the examplecode branch February 12, 2020 01:15
WesleyRosenblum added a commit that referenced this pull request Feb 12, 2020
…#151)

* Incorporate Keyrings into AwsCrypto and deprecate MasterKeyProviders.

* Update example code to use keyrings

* Using try-with-resources for AwsCrypto streams

* Splitting MKP and keyring unit tests

* Making decryptData with ParsedCiphertext public

* Mark KeyStoreProvider as deprecated

* Reword some comments on the Basic Encryption example

* Add test for compability of Keyrings with MasterKeyProviders

* Create individual request types for each AwsCrypto method

* Make EncryptionMaterials, DecryptionMaterials and KeyringTrace immutable

* Rename KmsKeying and related classes to AwsKmsKeyring

* Create builders for the standard keyrings

* Create AwsKmsCmkId type to represent AWS KMS Key Ids

* Add factory methods to Keyring builders

* Add comment on not making a defensive copy of plaintext/ciphertext

* Limit ability to create discovery AWS KMS Keyrings to explicit creation

* Add withKeyring to CachingCMM builder

* Fix DecryptRequestTest

* Fix Junit 4 assertions in JUnit5 tests

* Renaming StaticKeyring to TestKeyring

* Adding convenience methods the create builders internally

* Updating wording and adding more Deprecated annotations

* Enable AwsKms Client Caching by default to match KmsMasterKeyProvider

* Making tests opt-out instead of opt-in and update TestVectorRunner (#154)

* Making tests opt-out instead of opt-in and update TestVectorRunner

JUnit5 doesn't support test suites yet
(see junit-team/junit5#744) and the existing
test suites do not support the new JUnit5 tests that are being used for
keyrings. This change removes the test suites, and configures Maven to
include all tests except those marked with certain JUnit tags.

Additionally, this change updates the TestVectorRunner to also test
Keyrings and removes the redundant XCompat tests.

* Client caching is now enabled by default in AwsKmsClientSupplier

* Rename slow tag to ad_hoc and fix TestVectorRunner

* Renaming StandardKeyring builder methods and other minors changes

* Fixing test

* Updating tests to use assertThrows

* Additional example code for Keyrings (#155)

* Additional example code for Keyrings

* Updating wording

* Remove AWS from AWS KMS keyring and make keyring lowercase
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants