GemStone/S 64 Bit Supplemental Documentation

Data Encryption using AWS key management

Overview

GemStone supports key management using Amazon Web Services (AWS), on Linux and MacOS on Intel.

Amazon Web Services (AWS) provides tools and features that support applications running in the Amazon Cloud. AWS’s Key Management Service (KMS) provides a centralized way to securely manage cryptographic keys. New classes in GemStone allow you to use KMS for data encryption.

The AWS SDK for C++ (see https://github.com/aws/aws-sdk-cpp#aws-sdk-cpp) is an open-source project that provides a production-quality C++ interface to AWS. The GemStone now includes shared libraries based on the AWS toolkit. These libraries are included on Linux and Mac OS, which are the platforms that are supported by both the GemStone server and the AWS toolkit.

Versions 3.6.3 and 3.6.4 of GemStone include AWS SDK for C++ v1.9.140.

AWS Key Management

The following classes support this feature:

AbstractCloudCredentials - Abstract class, provided for future use

AwsCredentials - encapsulates the private and public keys needed for authentication to Amazon Web Services (AWS).

AbstractCloudKey - Abstract class, provided for future use

AwsDataKey - holds a local encryption key that can be used to encrypt and decrypt Strings and ByteArrays. This requires a CMK (Amazon Key Management Service’s Customer Master Key), and the AwsCredentials that are needed to authentication the CMK.

AwsError - signalled when errors occur in AWS API classes.

To use this feature, you must have an account with Amazon Web Services, have created an AWS Identity and Access Management (IAM) user, and obtained the credentials for that user. These will include an access key (aws_access_key_id) and a secret key (aws_secret_access_key). Access to KMS requires authentication using these AWS keys. Using KMS, you acquire a Customer Master Key (CMK), which is used for the encryption. Consult the AWS documentation, for more information.

GemStone’s API allows you to authenticate a CMK using the IAM credentials, and use the resulting key to encrypt a String or ByteArray, which can be decrypted using that key.

A key is created using code such as:

credentials := AwsCredentials
newWithAccessKeyId: 'AKIAIOSFODNN7EXAMPLE'
secretKeyId: 'wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY'.
cmk := 'arn:aws:kms:us-east-2:1234567890:key/12345-67890'.
key := AwsDataKey 
createKeyUsingAwsCredentials: validCreds 
cmsKeyId: cmk 
keySizeBytes: 16 

This instance of AwsDataKey should be persisted in the database for ongoing use for encryption and decryption. If the key instance is lost, any data that was encrypted with that key cannot be decrypted, and is permanently inaccessible, even if the credentials and CMK are available.

AwsCredentials can be recreated as needed. Since a persisted instance of AwsDataKey is locked in newly logged in sessions, the same or a recreated instance of AwsCredentials will be needed to unlock a persisted instance of AwsDataKey.

System clock

AWS request signing uses the system clock to include a timestamp in the signature. For this reason, AWS methods may fail if the system clock time is incorrect.

Locking

An AwsDataKey may be in a locked or unlocked state. A newly created key is unlocked. The key can be explicitly locked, and is automatically locked when the creating session logs out. If it is saved to disk, it is saved in the locked state.

If a key is locked, it cannot be used to encrypt or decrypt data. Before it can be used, it must be unlocked using an instance of AwsCredentials that can authenticate the CMK that is contained in the AwsDataKey.

The following methods are available:

AwsDataKey >> lock
AwsDataKey >> unlockWithAwsCredentials: anAwsCredentials
AwsDataKey >> isLocked
AwsDataKey >> isUnlocked

Encryption/decryption using the Key

Encryption and decryption done by sending a request to the (unlocked) AwsDataKey.

Encryption is performed using the AES-OCB authenticated encryption, which ensures data that has been successfully decrypted has not been modified in any way.

AwsDataKey >> encrypt: srcByteObj into: destByteObj
Uses the receiver to encrypt srcByteObj and stores the resulting encrypted bytes into destByteObj as a Base64 string. srcByteObj must be a non-empty byte object. destByteObj must be a mutable byte object; any contents will be overwritten.

AwsDataKey >> encryptAndErase: srcByteObj into: destByteObj
Encrypt srcByteObj, erasing all data in srcByteObj, and store the resulting encrypted bytes into destByteObj as a Base64 string. srcByteObj must be a non-empty byte object. destByteObj must be a mutable byte object; any contents will be overwritten.

AwsDataKey >> decrypt: srcByteObj into: destByteObj
Uses the receiver to decrypt srcByteObj and stores the resulting decrypted bytes into destByteObj. srcByteObj must be a non-empty byte object containing Base64 encrypted text. destByteObj must be an mutable byte object.; any contents will be overwritten.

For example

| credentials cmk key data encryptedData |
credentials := AwsCredentials
newWithAccessKeyId: 'AKIAIOSFODNN7EXAMPLE'
secretKeyId: 'wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY'.
cmk := 'arn:aws:kms:us-east-2:1234567890:key/12345-67890'.
key := AwsDataKey 
createKeyUsingAwsCredentials: validCreds 
cmsKeyId: cmk
keySizeBytes: 16.
data := 'Please excuse my dear aunt Sally'.
encryptedData String new.
key encrypt: data into: encryptedData.

Managing Keys

Key rotation

AWS KMS provides the ability to do key rotation for improved security. You may update an instance of AwsDataKey with a new CMS using the following method. To ensure that the change will be committed if successful, this method write locks the receiver and commits the session, so this requires that there are no uncommitted changes.

AwsDataKey >> changeCmsKeyIdTo: newCmsKeyId usingNewCredentials: newCreds
Atomically update the receiver to use newCmsKeyId, which is accessed with newCreds in a single operation, and commit. The receiver must be unlocked, the session must not have uncommitted changes, and the session must be able to write lock the receiver.

Making a copy of a key

An AwsDataKey can be copied. The copy of an AwsDataKey has the same locked state as the original, and can be unlocked using the same credentials.

AwsDataKey >> copy
Answer a new object which is a deep copy of the receiver. The lock state of the receiver is preserved when copied, i.e.: if the receiver is unlocked the resulting copy will also be unlocked.

Key equality

AwsDataKey objects are considered equal (=) if they have the same CMK (Customer Managed Key) string and the same encrypted key string. Lock state does not affect equality.