Skip to content

Update Readme for Keyrings #156

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 5 commits into from
Feb 12, 2020
Merged
Changes from 3 commits
Commits
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
100 changes: 58 additions & 42 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 @@ -54,7 +54,7 @@ You can get the latest release from Maven:
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-encryption-sdk-java</artifactId>
<version>1.6.1</version>
<version>1.7.0</version>
</dependency>
```

Expand All @@ -63,65 +63,81 @@ You can get the latest release from Maven:
The following code sample demonstrates how to get started:

1. Instantiate the SDK.
2. Define the master key provider.
2. Setup an AWS KMS Keyring.
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.
// This sample code encrypts and then decrypts data using an AWS KMS customer master key (CMK).
package com.amazonaws.crypto.examples;

import java.nio.charset.StandardCharsets;
import java.util.Arrays;
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;
import com.amazonaws.encryptionsdk.AwsCryptoResult;
import com.amazonaws.encryptionsdk.DecryptRequest;
import com.amazonaws.encryptionsdk.EncryptRequest;
import com.amazonaws.encryptionsdk.keyrings.Keyring;
import com.amazonaws.encryptionsdk.keyrings.StandardKeyrings;
import com.amazonaws.encryptionsdk.kms.AwsKmsCmkId;

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

private static final byte[] EXAMPLE_DATA = "Hello World".getBytes(StandardCharsets.UTF_8);

public static void main(final String[] args) {
keyArn = args[0];
data = args[1];
encryptAndDecrypt(AwsKmsCmkId.fromString(args[0]));
}

// Instantiate the SDK
static void encryptAndDecrypt(final AwsKmsCmkId keyArn) {
// 1. Instantiate the SDK
final AwsCrypto crypto = new AwsCrypto();

// Set up the master key provider
final KmsMasterKeyProvider prov = new KmsMasterKeyProvider(keyArn);
// 2. Instantiate an AWS KMS Keyring, supplying the key ARN as the generator for generating a
// data key. While using a key ARN is a best practice, for encryption operations it is also
// acceptable to use a CMK alias or an alias ARN.
final Keyring keyring = StandardKeyrings.awsKms(keyArn);

// Encrypt the data
// 3. Create an encryption context
//
// Most encrypted data should have an associated encryption context
// to protect integrity. This sample uses placeholder values.
//
// 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!");
// For more information see: https://amzn.to/1nSbe9X (blogs.aws.amazon.com)
final Map<String, String> encryptionContext = Collections.singletonMap("Example", "String");

// 4. Encrypt the data with the keyring and encryption context
final AwsCryptoResult<byte[]> encryptResult = crypto.encrypt(
EncryptRequest.builder()
.keyring(keyring)
.encryptionContext(encryptionContext)
.plaintext(EXAMPLE_DATA).build());
final byte[] ciphertext = encryptResult.getResult();

// 5. Decrypt the data. The same keyring may be used to encrypt and decrypt, but for decryption
// the key IDs must be in the key ARN format.
final AwsCryptoResult<byte[]> decryptResult = crypto.decrypt(
DecryptRequest.builder()
.keyring(keyring)
.ciphertext(ciphertext).build());

// 6. To verify the CMK that was actually used in the decrypt operation, inspect the keyring trace.
if(!decryptResult.getKeyringTrace().getEntries().get(0).getKeyName().equals(keyArn.toString())) {
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!");
}
}
// 7. 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.
//
// 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.
assert decryptResult.getEncryptionContext().get("Example").equals("String");

// The data is correct, so output it.
System.out.println("Decrypted: " + decryptResult.getResult());
// 8. Verify that the decrypted plaintext matches the original plaintext
assert Arrays.equals(decryptResult.getResult(), EXAMPLE_DATA);
}
}
```
Expand Down