AWS Encryption SDK for JavaScript examples - AWS Encryption SDK

AWS Encryption SDK for JavaScript examples

The following examples show you how to use the AWS Encryption SDK for JavaScript to encrypt and decrypt data.

You can find more examples of using the AWS Encryption SDK for JavaScript in the example-node and example-browser modules in the aws-encryption-sdk-javascript repository on GitHub. These example modules are not installed when you install the client-browser or client-node modules.

See the complete code samples: Node: kms_simple.ts, Browser: kms_simple.ts

Encrypting data with an AWS KMS keyring

The following example shows you how to use the AWS Encryption SDK for JavaScript to encrypt and decrypt a short string or byte array.

This example features an AWS KMS keyring, a type of keyring that uses an AWS KMS key to generate and encrypt data keys. For help creating an AWS KMS key, see Creating Keys in the AWS Key Management Service Developer Guide. For help identifying the AWS KMS keys in an AWS KMS keyring, see Identifying AWS KMS keys in an AWS KMS keyring

Step 1: Set the commitment policy.

Beginning in version 1.7.x of the AWS Encryption SDK for JavaScript, you can set the commitment policy when you call the new buildClient function that instantiates an AWS Encryption SDK client. The buildClient function takes an enumerated value that represents your commitment policy. It returns updated encrypt and decrypt functions that enforce your commitment policy when you encrypt and decrypt.

The following examples use the buildClient function to specify the default commitment policy, REQUIRE_ENCRYPT_REQUIRE_DECRYPT. You can also use the buildClient to limit the number of encrypted data keys in an encrypted message. For more information, see Limiting encrypted data keys.

JavaScript Browser
import { KmsKeyringBrowser, KMS, getClient, buildClient, CommitmentPolicy, } from '@aws-crypto/client-browser' const { encrypt, decrypt } = buildClient( CommitmentPolicy.REQUIRE_ENCRYPT_REQUIRE_DECRYPT )
JavaScript Node.js
import { KmsKeyringNode, buildClient, CommitmentPolicy, } from '@aws-crypto/client-node' const { encrypt, decrypt } = buildClient( CommitmentPolicy.REQUIRE_ENCRYPT_REQUIRE_DECRYPT )
Step 2: Construct the keyring.

Create an AWS KMS keyring for encryption.

When encrypting with an AWS KMS keyring, you must specify a generator key, that is, an AWS KMS key that is used to generate the plaintext data key and encrypt it. You can also specify zero or more additional keys that encrypt the same plaintext data key. The keyring returns the plaintext data key and one encrypted copy of that data key for each AWS KMS key in the keyring, including the generator key. To decrypt the data, you need to decrypt any one of the encrypted data keys.

To specify the AWS KMS keys for an encryption keyring in the AWS Encryption SDK for JavaScript, you can use any supported AWS KMS key identifier. This example uses a generator key, which is identified by its alias ARN, and one additional key, which is identified by a key ARN.

Note

If you plan to reuse your AWS KMS keyring for decrypting, you must use key ARNs to identify the AWS KMS keys in the keyring.

Before running this code, replace the example AWS KMS key identifiers with valid identifiers. You must have the permissions required to use the AWS KMS keys in the keyring.

JavaScript Browser

Begin by providing your credentials to the browser. The AWS Encryption SDK for JavaScript examples use the webpack.DefinePlugin, which replaces the credential constants with your actual credentials. But you can use any method to provide your credentials. Then, use the credentials to create an AWS KMS client.

declare const credentials: {accessKeyId: string, secretAccessKey:string, sessionToken:string } const clientProvider = getClient(KMS, { credentials: { accessKeyId, secretAccessKey, sessionToken } })

Next, specify the AWS KMS keys for the generator key and additional key. Then, create an AWS KMS keyring using the AWS KMS client and the AWS KMS keys.

const generatorKeyId = 'arn:aws:kms:us-west-2:111122223333:alias/EncryptDecrypt' const keyIds = ['arn:aws:kms:us-west-2:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab'] const keyring = new KmsKeyringBrowser({ clientProvider, generatorKeyId, keyIds })
JavaScript Node.js
const generatorKeyId = 'arn:aws:kms:us-west-2:111122223333:alias/EncryptDecrypt' const keyIds = ['arn:aws:kms:us-west-2:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab'] const keyring = new KmsKeyringNode({ generatorKeyId, keyIds })
Step 3: Set the encryption context.

An encryption context is arbitrary, non-secret additional authenticated data. When you provide an encryption context on encrypt, the AWS Encryption SDK cryptographically binds the encryption context to the ciphertext so that the same encryption context is required to decrypt the data. Using an encryption context is optional, but we recommend it as a best practice.

Create a simple object that includes the encryption context pairs. The key and value in each pair must be a string.

JavaScript Browser
const context = { stage: 'demo', purpose: 'simple demonstration app', origin: 'us-west-2' }
JavaScript Node.js
const context = { stage: 'demo', purpose: 'simple demonstration app', origin: 'us-west-2' }
Step 4: Encrypt the data.

To encrypt the plaintext data, call the encrypt function. Pass in the AWS KMS keyring, the plaintext data, and the encryption context.

The encrypt function returns an encrypted message (result) that contains the encrypted data, the encrypted data keys, and important metadata, including the encryption context and signature.

You can decrypt this encrypted message by using the AWS Encryption SDK for any supported programming language.

JavaScript Browser
const plaintext = new Uint8Array([1, 2, 3, 4, 5]) const { result } = await encrypt(keyring, plaintext, { encryptionContext: context })
JavaScript Node.js
const plaintext = 'asdf' const { result } = await encrypt(keyring, plaintext, { encryptionContext: context })

Decrypting data with an AWS KMS keyring

You can use the AWS Encryption SDK for JavaScript to decrypt the encrypted message and recover the original data.

In this example, we decrypt the data that we encrypted in the Encrypting data with an AWS KMS keyring example.

Step 1: Set the commitment policy.

Beginning in version 1.7.x of the AWS Encryption SDK for JavaScript, you can set the commitment policy when you call the new buildClient function that instantiates an AWS Encryption SDK client. The buildClient function takes an enumerated value that represents your commitment policy. It returns updated encrypt and decrypt functions that enforce your commitment policy when you encrypt and decrypt.

The following examples use the buildClient function to specify the default commitment policy, REQUIRE_ENCRYPT_REQUIRE_DECRYPT. You can also use the buildClient to limit the number of encrypted data keys in an encrypted message. For more information, see Limiting encrypted data keys.

JavaScript Browser
import { KmsKeyringBrowser, KMS, getClient, buildClient, CommitmentPolicy, } from '@aws-crypto/client-browser' const { encrypt, decrypt } = buildClient( CommitmentPolicy.REQUIRE_ENCRYPT_REQUIRE_DECRYPT )
JavaScript Node.js
import { KmsKeyringNode, buildClient, CommitmentPolicy, } from '@aws-crypto/client-node' const { encrypt, decrypt } = buildClient( CommitmentPolicy.REQUIRE_ENCRYPT_REQUIRE_DECRYPT )
Step 2: Construct the keyring.

To decrypt the data, pass in the encrypted message (result) that the encrypt function returned. The encrypted message includes the encrypted data, the encrypted data keys, and important metadata, including the encryption context and signature.

You must also specify an AWS KMS keyring when decrypting. You can use the same keyring that was used to encrypt the data or a different keyring. To succeed, at least one AWS KMS key in the decryption keyring must be able to decrypt one of the encrypted data keys in the encrypted message. Because no data keys are generated, you do not need to specify a generator key in a decryption keyring. If you do, the generator key and additional keys are treated the same way.

To specify an AWS KMS key for a decryption keyring in the AWS Encryption SDK for JavaScript, you must use the key ARN. Otherwise, the AWS KMS key is not recognized. For help identifying the AWS KMS keys in an AWS KMS keyring, see Identifying AWS KMS keys in an AWS KMS keyring

Note

If you use the same keyring for encrypting and decrypting, use key ARNs to identify the AWS KMS keys in the keyring.

In this example, we create a keyring that includes only one of the AWS KMS keys in the encryption keyring. Before running this code, replace the example key ARN with a valid one. You must have kms:Decrypt permission on the AWS KMS key.

JavaScript Browser

Begin by providing your credentials to the browser. The AWS Encryption SDK for JavaScript examples use the webpack.DefinePlugin, which replaces the credential constants with your actual credentials. But you can use any method to provide your credentials. Then, use the credentials to create an AWS KMS client.

declare const credentials: {accessKeyId: string, secretAccessKey:string, sessionToken:string } const clientProvider = getClient(KMS, { credentials: { accessKeyId, secretAccessKey, sessionToken } })

Next, create an AWS KMS keyring using the AWS KMS client. This example uses just one of the AWS KMS keys from the encryption keyring.

const keyIds = ['arn:aws:kms:us-west-2:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab'] const keyring = new KmsKeyringBrowser({ clientProvider, keyIds })
JavaScript Node.js
const keyIds = ['arn:aws:kms:us-west-2:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab'] const keyring = new KmsKeyringNode({ keyIds })
Step 3: Decrypt the data.

Next, call the decrypt function. Pass in the decryption keyring that you just created (keyring) and the encrypted message that the encrypt function returned (result). The AWS Encryption SDK uses the keyring to decrypt one of the encrypted data keys. Then it uses the plaintext data key to decrypt the data.

If the call succeeds, the plaintext field contains the plaintext (decrypted) data. The messageHeader field contains metadata about the decryption process, including the encryption context that was used to decrypt the data.

JavaScript Browser
const { plaintext, messageHeader } = await decrypt(keyring, result)
JavaScript Node.js
const { plaintext, messageHeader } = await decrypt(keyring, result)
Step 4: Verify the encryption context.

The encryption context that was used to decrypt the data is included in the message header (messageHeader) that the decrypt function returns. Before your application returns the plaintext data, verify that the encryption context that you provided when encrypting is included in the encryption context that was used when decrypting. A mismatch might indicate that the data was tampered with, or that you didn't decrypt the right ciphertext.

When verifying the encryption context, do not require an exact match. When you use an encryption algorithm with signing, the cryptographic materials manager (CMM) adds the public signing key to the encryption context before encrypting the message. But all of the encryption context pairs that you submitted should be included in the encryption context that was returned.

First, get the encryption context from the message header. Then, verify that each key-value pair in the original encryption context (context) matches a key-value pair in the returned encryption context (encryptionContext).

JavaScript Browser
const { encryptionContext } = messageHeader Object .entries(context) .forEach(([key, value]) => { if (encryptionContext[key] !== value) throw new Error('Encryption Context does not match expected values') })
JavaScript Node.js
const { encryptionContext } = messageHeader Object .entries(context) .forEach(([key, value]) => { if (encryptionContext[key] !== value) throw new Error('Encryption Context does not match expected values') })

If the encryption context check succeeds, you can return the plaintext data.