Client-Side Encryption

The Oracle Cloud Infrastructure SDK for Python and SDK for Java support Client Side Encryption, which encrypts your data on the client side before storing it locally or using it with other Oracle Cloud Infrastructure services.

By default, the SDK generates a unique data key for each data object that it encrypts. Data is encrypted using a secure, authenticated, symmetric AES/GCM key algorithm with a 256-bit key length.

To use client-side encryption, you must create a master encryption key (MEK) using the Key Management Service. This can be done using the CreateKey or ImportKey operations.

The MEK is used to generate a Data Encryption Key (DEK) to encrypt each payload. A encrypted copy of this DEK (encrypted under the MEK) and other pieces of metadata are included in the encrypted payload returned by the SDKs so that they can be used for decryption.

Java Prerequisites

The unlimited policy files for earlier releases are required only for JDK 8, 7, and 6 updates earlier than 8u161, 7u171, and 6u16. For those versions and later the policy files are included but not enabled by default.

Current versions of the JDK do not require these policy files. They are provided here for use with older versions of the JDK. JDK 9 and later ship with the unlimited policy files and use them by default.

Examples

The following code example show how to encrypt a string:

Java

// String encryption example
			
final byte[] plainText = "Hello World".getBytes();
String masterKeyId = "OCID....";
Map<String, String> context = Collections.singletonMap("Example", "value");
 
OciCrypto ociCrypto = new OciCrypto();
KmsMasterKey kmsMasterKey = new KmsMasterKey(authenticationProvider, Region.US_ASHBURN_1.getRegionId(), vaultId, masterKeyId);
KmsMasterKeyProvider kmsMasterKeyProvider = new KmsMasterKeyProvider(kmsMasterKey);
 
//  Encrypt the data and embed the master key ID in the header
final OciCryptoResult encryptResult = ociCrypto.encryptData(kmsMasterKeyProvider, plainText, context);
final byte[] cipherText = encryptResult.getResult();
 
//  Decrypt the data
final OciCryptoResult decryptResult = ociCrypto.decryptData(kmsMasterKeyProvider, cipherText);

Python

import oci
 
# user supplied vars
vault_id = TEST_VAULT_OCID
master_key_id = TEST_MASTER_KEY_ID
data_to_encrypt_bytes = b"This is a secret message"
 
config = oci.config.from_file()
kms_master_key = oci.encryption.KMSMasterKey(
    config=config, master_key_id=master_key_id, vault_id=vault_id
)
 
kms_master_key_provider = oci.encryption.KMSMasterKeyProvider(
    config=config,
    kms_master_keys=[kms_master_key]
)
 
crypto_result = crypto.encrypt(kms_master_key_provider, data_to_encrypt_bytes)
ciphertext = crypto_result.get_data()
print("ciphertext: {}".format(ciphertext))
 
# decrypt string example
crypto_result = crypto.decrypt(ciphertext, kms_master_key_provider)
print("unencrypted text: {}".format(crypto_result.get_data()))

The following examples show how to encrypt a file stream:

Java

// Create Encryption file stream
FileInputStream in = new FileInputStream(srcFile);
OciCrypto ociCrypto = new OciCrypto();
KmsMasterKey kmsMasterKey = new KmsMasterKey(authenticationProvider, Region.US_ASHBURN_1.getRegionId(), vaultId, masterKeyId);
KmsMasterKeyProvider kmsMasterKeyProvider = new KmsMasterKeyProvider(kmsMasterKey);
OciCryptoInputStream encryptingStream = ociCrypto.createEncryptingStream(kmsMasterKeyProvider, in);
 
// Write the encrypted data to file
FileOutputStream out = new FileOutputStream(srcFile + ".encrypted");
IOUtils.copy(encryptingStream, out);
encryptingStream.close();
out.close();
 
// For decryption, no need to pass key info
KmsMasterKeyProvider kmsMasterKeyProvider = new KmsMasterKeyProvider(authenticationProvider);
// Create the Decryption file stream.
in = new FileInputStream(srcFile + ".encrypted");
OciCryptoInputStream decryptingStream = ociCrypto.createDecryptingStream(kmsMasterKeyProvider, in);
 
 
// Return the plaintext data
out = new FileOutputStream(srcFile + ".decrypted");
IOUtils.copy(decryptingStream, out);
decryptingStream.close();
out.close();

Python

import oci
import shutil
 
# user supplied vars
vault_id = TEST_VAULT_OCID
master_key_id = TEST_MASTER_KEY_ID
file_to_encrypt = "/file/to/encrypt/message.txt"
output_encrypted_file = "/tmp/message.txt.encrypted"
output_decrypted_file = "/tmp/message.txt.decrypted"
 
# setup OCI KMS keys
config = oci.config.from_file()
kms_master_key = oci.encryption.KMSMasterKey(
    config=config, master_key_id=master_key_id, vault_id=vault_id
)
 
kms_master_key_provider = oci.encryption.KMSMasterKeyProvider(
    config=config,
    kms_master_keys=[kms_master_key]
)
 
# encrypt stream example
with open(output_encrypted_file, 'wb') as output_stream, open(file_to_encrypt, 'rb') as stream_to_encrypt:
    with crypto.create_encryption_stream(
        kms_master_key_provider,
        stream_to_encrypt
    ) as encryption_stream:
        shutil.copyfileobj(encryption_stream, output_stream)
 
# decrypt stream example
with open(output_decrypted_file, 'wb') as output_stream, open(output_encrypted_file, 'rb') as stream_to_decrypt:
    with crypto.create_decryption_stream(
        stream_to_decrypt,
        kms_master_key_provider
    ) as decryption_stream:
        shutil.copyfileobj(decryption_stream, output_stream)