AWS Developer Tools Blog

Using Client-Side Encryption for Amazon S3 in the AWS SDK for PHP

The AWS SDK for PHP released an S3EncryptionClient in version 3.38.0. With client-side encryption, data is encrypted and decrypted directly in your environment. This means that this data is encrypted before it’s transferred to Amazon S3, and you don’t rely on an external service to handle encryption for you.

The AWS SDK for PHP implements envelope encryption and uses OpenSSL for its encrypting and decrypting. The implementation is interoperable with other SDKs that match its feature support. It’s also compatible with the SDK’s promise-based asynchronous workflow.

Setup

To get started with these client-side encryption examples, you need the following:

Encryption

Uploading an encrypted object through the PutObject operation takes a similar interface and requires two new parameters. Let’s take a look:

	
	// Let's construct our S3EncryptionClient using an S3Client
	$encryptionClient = new S3EncryptionClient(
		new S3Client([
			'region' => 'us-east-1',
			'version' => 'latest',
		])
	);

	$kmsKeyArn = 'arn-to-the-kms-key';
	// This materials provider handles generating a cipher key and initialization
	// vector, as well as encrypting your cipher key via AWS KMS
	$materialsProvider = new KmsMaterialsProvider(
		new KmsClient([
			'region' => 'us-east-1',
			'version' => 'latest',
		]),
		$kmsKeyArn
	);

	$bucket = 'the-bucket-name';
	$key = 'the-upload-key';
	$cipherOptions = [
		'Cipher' => 'gcm'
		'KeySize' => 256,
		// Additional configuration options
	];

	$result = $encryptionClient->putObject([
		'@MaterialsProvider' => $materialsProvider,
		'@CipherOptions' => $cipherOptions,
		'Bucket' => $bucket,
		'Key' => $key,
		'Body' => fopen('file-to-encrypt.txt'),
	]);
	

Decryption

Downloading and decrypting an object requires only one additional parameter on top of GetObject, and the client will detect the basic cipher options for you. Additional configuration options are passed through for decryption.

	
	$result = $encryptionClient->getObject([
		'@MaterialsProvider' => $materialsProvider,
		'@CipherOptions' => [
			// Additional configuration options
		], 
		'Bucket' => $bucket,
		'Key' => $key,
	]);
	

Going further

The S3EncryptionClient gives you access to other fields. These include an additional authentication data (‘Aad’) string to put in your $cipherOptions and the ability to define a MetadataStrategy. You can find more information about these topics in the service guide.

You can also check out other AWS SDKs that support the Amazon S3 encryption client: