Skip to content

Merge keyring branch into master #173

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 20 commits into from
Apr 13, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
9307933
Create keyring trace and add to encryption and decryption materials. …
WesleyRosenblum Oct 30, 2019
282cd6f
Merge head of master into keyring (#141)
WesleyRosenblum Nov 9, 2019
36958b8
Defining Keyring interface, RawAesKeyring and RawRsaKeyring. (#142)
WesleyRosenblum Nov 21, 2019
b75027d
Define the MultiKeyring (#148)
WesleyRosenblum Dec 18, 2019
77f46c2
Defining the KMS Keyring (#147)
WesleyRosenblum Dec 18, 2019
a6893b6
Define the MasterKeyProvider Keyring. (#149)
WesleyRosenblum Dec 18, 2019
1ee9643
Using original Materials classes instead of new Keyring classes (#152)
WesleyRosenblum Jan 23, 2020
8bdb1d4
Incorporate Keyrings into AwsCrypto and deprecate MasterKeyProviders.…
WesleyRosenblum Feb 12, 2020
8705f16
Update Readme for Keyrings (#156)
WesleyRosenblum Feb 12, 2020
f4973ec
Adding a simple example of data key caching (#158)
WesleyRosenblum Feb 20, 2020
d15f988
Have Lambda example cache data keys in a static field.
SalusaSecondus Mar 6, 2020
2055728
Define an enum for the RSA padding scheme (#162)
WesleyRosenblum Mar 10, 2020
c60ad59
Making client suppliers composable (#163)
WesleyRosenblum Mar 16, 2020
2d025a8
Adding new examples and example test runner (#165)
WesleyRosenblum Mar 31, 2020
b893a0e
Add master key provider examples (#168)
WesleyRosenblum Apr 6, 2020
ebda774
Merge head of master into keyring (#169)
WesleyRosenblum Apr 7, 2020
b16af24
add CMM examples (#170)
WesleyRosenblum Apr 9, 2020
a9a6abd
Remove inline example code from readme and reset version number (#171)
WesleyRosenblum Apr 10, 2020
b355858
Merge branch 'master' into keyring-master-merge
WesleyRosenblum Apr 10, 2020
5cf7e0c
Merge pull request #172 from aws/keyring-master-merge
WesleyRosenblum Apr 10, 2020
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
74 changes: 4 additions & 70 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
# AWS Encryption SDK for Java

The AWS Encryption SDK enables secure client-side encryption. It uses cryptography best practices to protect your data and the encryption keys used to protect that data. Each data object is protected with a unique data encryption key (DEK), and the DEK is protected with a key encryption key (KEK) called a *master key*. The encrypted DEK is combined with the encrypted data into a single [encrypted message](https://docs.aws.amazon.com/encryption-sdk/latest/developer-guide/message-format.html), so you don't need to keep track of the DEKs for your data. The SDK supports master keys in [AWS Key Management Service](https://aws.amazon.com/kms/) (KMS), and it also provides APIs to define and use other master key providers. The SDK provides methods for encrypting and decrypting strings, byte arrays, and byte streams. For details, see the [example code][examples] and the [Javadoc](https://aws.github.io/aws-encryption-sdk-java/javadoc/).
The AWS Encryption SDK is a client-side encryption library designed to make it easy for everyone to encrypt and decrypt data using industry standards and best practices. It enables you to focus on the core functionality of your application, rather than on how to best encrypt and decrypt your data.

For more details about the design and architecture of the SDK, see the [official documentation](https://docs.aws.amazon.com/encryption-sdk/latest/developer-guide/).
For details about the design, architecture and usage of the SDK, see the [official documentation](https://docs.aws.amazon.com/encryption-sdk/latest/developer-guide/), [example code][examples] and the [Javadoc](https://aws.github.io/aws-encryption-sdk-java/javadoc/).

## Getting Started

Expand Down Expand Up @@ -58,75 +58,9 @@ You can get the latest release from Maven:
</dependency>
```

### Get Started

The following code sample demonstrates how to get started:

1. Instantiate the SDK.
2. Define the master key provider.
3. Encrypt and decrypt data.

```java
// This sample code encrypts and then decrypts a string using a KMS CMK.
// You provide the KMS key ARN and plaintext string as arguments.
package com.amazonaws.crypto.examples;

import java.util.Collections;
import java.util.Map;

import com.amazonaws.encryptionsdk.AwsCrypto;
import com.amazonaws.encryptionsdk.CryptoResult;
import com.amazonaws.encryptionsdk.kms.KmsMasterKey;
import com.amazonaws.encryptionsdk.kms.KmsMasterKeyProvider;

public class StringExample {
private static String keyArn;
private static String data;

public static void main(final String[] args) {
keyArn = args[0];
data = args[1];

// Instantiate the SDK
final AwsCrypto crypto = new AwsCrypto();

// Set up the master key provider
final KmsMasterKeyProvider prov = new KmsMasterKeyProvider(keyArn);

// Encrypt the data
//
// NOTE: Encrypted data should have associated encryption context
// to protect integrity. For this example, just use a placeholder
// value. For more information about encryption context, see
// https://amzn.to/1nSbe9X (blogs.aws.amazon.com)
final Map<String, String> context = Collections.singletonMap("Example", "String");

final String ciphertext = crypto.encryptString(prov, data, context).getResult();
System.out.println("Ciphertext: " + ciphertext);

// Decrypt the data
final CryptoResult<String, KmsMasterKey> decryptResult = crypto.decryptString(prov, ciphertext);
// Check the encryption context (and ideally the master key) to
// ensure this is the expected ciphertext
if (!decryptResult.getMasterKeyIds().get(0).equals(keyArn)) {
throw new IllegalStateException("Wrong key id!");
}

// The SDK may add information to the encryption context, so check to
// ensure all of the values are present
for (final Map.Entry<String, String> e : context.entrySet()) {
if (!e.getValue().equals(decryptResult.getEncryptionContext().get(e.getKey()))) {
throw new IllegalStateException("Wrong Encryption Context!");
}
}

// The data is correct, so output it.
System.out.println("Decrypted: " + decryptResult.getResult());
}
}
```
### Sample Code

You can find more examples in the [examples directory][examples].
You can find sample code in the [examples directory][examples].

## Public API

Expand Down
74 changes: 57 additions & 17 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-java-sdk</artifactId>
<version>1.11.561</version>
<version>1.11.677</version>
<optional>true</optional>
</dependency>

Expand All @@ -53,16 +53,23 @@
</dependency>

<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>2.28.1</version>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>5.5.2</version>
<scope>test</scope>
</dependency>

<dependency>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
<version>5.5.2</version>
<scope>test</scope>
</dependency>

<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<groupId>org.mockito</groupId>
<artifactId>mockito-junit-jupiter</artifactId>
<version>3.1.0</version>
<scope>test</scope>
</dependency>

Expand All @@ -73,6 +80,19 @@
<scope>test</scope>
</dependency>

<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-lambda-java-core</artifactId>
<version>1.2.0</version>
<scope>test</scope>
</dependency>

<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-lambda-java-events</artifactId>
<version>2.2.7</version>
<scope>test</scope>
</dependency>

<dependency>
<groupId>com.google.code.findbugs</groupId>
Expand Down Expand Up @@ -190,7 +210,7 @@
</profile>

<profile>
<id>full-test-suite</id>
<id>test-suite</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
Expand All @@ -201,30 +221,50 @@
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.0</version>
<configuration>
<includes>
<include>**/AllTestsSuite.java</include>
</includes>
<excludedGroups>ad_hoc</excludedGroups>
</configuration>
</plugin>
</plugins>
</build>
</profile>

<!-- This test profile is intended to assist in rapid development; it filters out some of the slower,
more exhaustive tests in the overall test suite to allow for a rapid edit-test cycle. -->
<profile>
<id>fast-tests-only</id>
<activation>
<activeByDefault>false</activeByDefault>
</activation>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.0</version>
<configuration>
<includes>
<include>**/FastTestsOnlySuite.java</include>
</includes>
<excludedGroups>ad_hoc, integration</excludedGroups>
<systemPropertyVariables>
<fastTestsOnly>true</fastTestsOnly>
</systemPropertyVariables>
<!-- Require that this fast suite completes relatively quickly. If you're seeing
this timeout get hit, it's time to pare down tests some more. As a general rule of
thumb, we should avoid any single test taking more than 10s, and try to keep the
number of such slow tests to a minimum. -->
<forkedProcessTimeoutInSeconds>120</forkedProcessTimeoutInSeconds>
</configuration>
</plugin>
</plugins>
</build>
</profile>

<!-- This test profile will run only the integration tests. -->
<profile>
<id>integration</id>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.0</version>
<configuration>
<groups>integration</groups>
</configuration>
</plugin>
</plugins>
Expand Down
126 changes: 126 additions & 0 deletions src/examples/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
# AWS Encryption SDK Examples

This section features examples that show you
how to use the AWS Encryption SDK.
We demonstrate how to use the encryption and decryption APIs
and how to set up some common configuration patterns.

## APIs

The AWS Encryption SDK provides two high-level APIs:
one-step APIs that process the entire operation in memory
and streaming APIs.

You can find examples that demonstrate these APIs
in the [`examples`](./java/com/amazonaws/crypto/examples) directory.

## Configuration

To use the encryption and decryption APIs,
you need to describe how you want the library to protect your data keys.
You can do this by configuring
[keyrings](#keyrings) or [cryptographic materials managers](#cryptographic-materials-managers),
or by configuring [master key providers](#master-key-providers).
These examples will show you how to use the configuration tools that we include for you
and how to create some of your own.
We start with AWS KMS examples, then show how to use other wrapping keys.

* Using AWS Key Management Service (AWS KMS)
* How to use one AWS KMS CMK
* [with keyrings](./java/com/amazonaws/crypto/examples/keyring/awskms/SingleCmk.java)
* [with master key providers](./java/com/amazonaws/crypto/examples/masterkeyprovider/awskms/SingleCmk.java)
* How to use multiple AWS KMS CMKs in different regions
* [with keyrings](./java/com/amazonaws/crypto/examples/keyring/awskms/MultipleRegions.java)
* [with master key providers](./java/com/amazonaws/crypto/examples/masterkeyprovider/awskms/MultipleRegions.java)
* How to decrypt when you don't know the CMK
* [with keyrings](./java/com/amazonaws/crypto/examples/keyring/awskms/DiscoveryDecrypt.java)
* [with master key providers](./java/com/amazonaws/crypto/examples/masterkeyprovider/awskms/DiscoveryDecrypt.java)
* How to decrypt within a region
* [with keyrings](./java/com/amazonaws/crypto/examples/keyring/awskms/DiscoveryDecryptInRegionOnly.java)
* How to decrypt with a preferred region but failover to others
* [with keyrings](./java/com/amazonaws/crypto/examples/keyring/awskms/DiscoveryDecryptWithPreferredRegions.java)
* Using raw wrapping keys
* How to use a raw AES wrapping key
* [with keyrings](./java/com/amazonaws/crypto/examples/keyring/rawaes/RawAes.java)
* [with master key providers](./java/com/amazonaws/crypto/examples/masterkeyprovider/rawaes/RawAes.java)
* How to use a raw RSA wrapping key
* [with keyrings](./java/com/amazonaws/crypto/examples/keyring/rawrsa/RawRsa.java)
* [with master key providers](./java/com/amazonaws/crypto/examples/masterkeyprovider/rawrsa/RawRsa.java)
* How to encrypt with a raw RSA public key wrapping key without access to the private key
* [with keyrings](./java/com/amazonaws/crypto/examples/keyring/rawrsa/PublicPrivateKeySeparate.java)
* How to use a raw RSA wrapping key when the key is DER encoded
* [with keyrings](./java/com/amazonaws/crypto/examples/keyring/rawrsa/RawRsaDerEncoded.java)
* Combining wrapping keys
* How to combine AWS KMS with an offline escrow key
* [with keyrings](./java/com/amazonaws/crypto/examples/keyring/multi/AwsKmsWithEscrow.java)
* [with master key providers](./java/com/amazonaws/crypto/examples/masterkeyprovider/multi/AwsKmsWithEscrow.java)
* How to reuse data keys across multiple messages
* [with the caching cryptographic materials manager](./java/com/amazonaws/crypto/examples/cryptomaterialsmanager/caching/SimpleCache.java)
* How to restrict algorithm suites
* [with a custom cryptographic materials manager](./java/com/amazonaws/crypto/examples/cryptomaterialsmanager/custom/AlgorithmSuiteEnforcement.java)
* How to require encryption context fields
* [with a custom cryptographic materials manager](./java/com/amazonaws/crypto/examples/cryptomaterialsmanager/custom/RequiringEncryptionContextFields.java)

### Keyrings

Keyrings are the most common way for you to configure the AWS Encryption SDK.
They determine how the AWS Encryption SDK protects your data.
You can find these examples in ['examples/keyring`](./java/com/amazonaws/crypto/examples/keyring).

### Cryptographic Materials Managers

Keyrings define how your data keys are protected,
but there is more going on here than just protecting data keys.

Cryptographic materials managers give you higher-level controls
over how the AWS Encryption SDK protects your data.
This can include things like
enforcing the use of certain algorithm suites or encryption context settings,
reusing data keys across messages,
or changing how you interact with keyrings.
You can find these examples in
[`examples/crypto_materials_manager`](./java/com/amazonaws/crypto/examples/cryptomaterialsmanager).

### Master Key Providers

Before there were keyrings, there were master key providers.
Master key providers were the original configuration structure
that we provided for defining how you want to protect your data keys.
Keyrings provide a simpler experience and often more powerful configuration options,
but if you need to use master key providers,
need help migrating from master key providers to keyrings,
or simply want to see the difference between these configuration experiences,
you can find these examples in [`examples/masterkeyprovider`](./java/com/amazonaws/crypto/examples/masterkeyprovider).

## Legacy

This section includes older examples,
including examples of using master keys and master key providers.
You can use them as a reference,
but we recommend looking at the newer examples, which explain the preferred ways of using this library.
You can find these examples in [`examples/legacy`](./java/com/amazonaws/crypto/examples/legacy).

# Writing Examples

If you want to contribute a new example, that's awesome!
To make sure that your example is tested in our CI,
please make sure that it meets the following requirements:

1. The example MUST be a distinct class in the [`examples`](./java/com/amazonaws/crypto/examples) directory.
1. Each example file MUST contain exactly one example.
1. Each example file MUST contain a static method called `run` that runs the example.
1. If your `run` method needs any of the following inputs,
the parameters MUST have the following types:
* `com.amazonaws.encryptionsdk.kms.AwsKmsCmkId` : A single AWS KMS CMK ARN.
* NOTE: You can assume that automatically discovered credentials have
`kms:GenerateDataKey`, `kms:Encrypt`, and `kms:Decrypt` permissions on this CMK.
* `List<com.amazonaws.encryptionsdk.kms.AwsKmsCmkId>` :
A list of AWS KMS CMK ARNs to use for encrypting and decrypting data keys.
* NOTE: You can assume that automatically discovered credentials have
`kms:Encrypt` and `kms:Decrypt` permissions on these CMKs.
* `byte[]` : Plaintext data to encrypt.
* `java.io.File` : A path to a file containing plaintext to encrypt.
* NOTE: You can assume that you have write access to the parent directory
and that anything you do in that directory will be cleaned up
by our test runners.
1. Any additional parameters MUST be optional and nullable and not of the same type as the above parameters.
Loading