AWS Developer Tools Blog

S3 Server Side Encryption with Windows PowerShell

Today we have a guest post by AWS Solutions Architect David Veith on making use of Amazon S3’s server-side encryption with customer-provided keys.

The release of version 2.1.4 of the AWS Tools for Windows PowerShell introduced support for a new server-side encryption method for Amazon S3. You now have three primary options for encrypting data at rest in S3:

  • You can secure your sensitive data before you ever send it to AWS by using client-side encryption.
  • You can use S3’s built-in server-side encryption (SSE), so your data is encrypted with AWS keys and processes while AWS manages the keys.
  • And now you can get all of the benefits and ease of use of server-side encryption, but with your own customer-provided keys (SSE-C).

This blog post describes how you can use the AWS PowerShell tools to secure your data at rest with S3 with the two methods of S3 server-side encryption (SSE-C and SSE).

Server-Side Encryption with Customer-Provided Keys (SSE-C)

With SSE-C, S3 encrypts your data on your behalf using keys that you provide and manage. Because S3 performs the encryption for you, you get the benefits of using your encryption keys without the burden or cost of writing or executing your own encryption code. This method of encryption is not available via the AWS console.

Protecting Your Keys

S3 discards your key immediately upon encrypting/decrypting your object; because the key is never retained, you lose your object if you lose your key. For this reason, it is very important to take special precautions to store your keys safely and securely. If you use multiple keys, you are responsible for tracking which encryption key you provided for each object. You should also consider implementing an envelope encryption process when storing encrypted objects in S3, as described in the article Client-Side Data Encryption with the AWS SDK for Java and Amazon S3.

Creating Your Key

The following commands use the .NET AES class in System.Security.Cryptography to create a base64 encoded key.

$Aes = New-Object System.Security.Cryptography.AesManaged
$Aes.KeySize = 256
$Aes::GenerateKey
$Base64key = [System.Convert]::ToBase64String($Aes.Key)

Writing an Object (SSE-C)

The Write-S3Object cmdlet is used to store an object in S3, encrypting it at rest using a client-provided key. The key is base64 encoded and the encryption method is specified as AES256. After your object is encrypted, your key is discarded.

$initialfile  = "YourFile"
$bucket       = "YourBucketName"
$objectkey    = "YourKeyName" 

try 
{
	Write-S3Object -Region us-west-2 -File $initialfile -BucketName $bucket -Key $objectkey -ServerSideEncryptionCustomerProvidedKey $Base64key -ServerSideEncryptionCustomerMethod AES256
}
catch [system.exception] 
{
	Write-Host  "Error: " $_.Exception.Message
}

Reading an Object (SSE-C)

The Read-S3Object cmdlet is used to retrieve an encrypted object in S3 using the same client-provided key that was used to encrypt it when it was originally stored in S3. The key is base64-encoded and the encryption method is specified as AES256. After your object is decrypted, your key is discarded.

$ssecfileout  = "YourOutputFile" 
$bucket       = "YourBucketName"
$objectkey    = "YourKeyName" 

try 
{
	Read-S3Object -Region us-west-2 -BucketName $bucket -Key $objectkey -File $ssecfileout  -ServerSideEncryptionCustomerProvidedKey $Base64key -ServerSideEncryptionCustomerMethod AES256
}
catch [system.exception]
{
	Write-Host  "Error: " $_.Exception.Message
}

Copying an Object (SSE-C)

The Copy-S3Object cmdlet is used to copy an encrypted object in S3 to a new key. Two keys are required for this scenario. The first key is required to decrypt the original object (because S3 never stores the key). The second key is used to encrypt the new copy. In this case, we used the same encryption key and the same bucket but that is not a requirement. As always, your keys are discarded after use.

$bucket         = "YourBucketName"
$objectkey      = "YourKeyName" 
$copyobjectkey  = "YourDestinationKeyName"

try 
{
	Copy-S3Object -Region us-west-2 -BucketName $bucket -Key $objectkey -DestinationBucket $bucket  -DestinationKey $copyobjectkey -CopySourceServerSideEncryptionCustomerMethod AES256 -CopySourceServerSideEncryptionCustomerProvidedKey $Base64key -ServerSideEncryptionCustomerProvidedKey $Base64key -ServerSideEncryptionCustomerMethod AES256
}
catch [system.exception] 
{
	Write-Host  "Error: " $_.Exception.Message
}

S3 Server-Side Encryption (SSE) with AWS Keys

This is the simplest method of encrypting your data at rest in S3. With SSE, S3 encrypts your data on your behalf using AWS keys and processes. You don’t need to track, store or provide any encryption keys. This method of encryption is also available via the AWS console.

Writing an Object (SSE)

As mentioned earlier, the Write-S3Object cmdlet is used to store an object in S3, in this case, encrypting the object on disk using AWS encryption and keys.

$initialfile  = "YourFile"
$bucket       = "YourBucketName"
$objectkey    = "YourKeyName" 

try 
{
	Write-S3Object -Region us-west-2 -File $initialfile -BucketName $bucket -Key $objectkey -ServerSideEncryption AES256
}
catch [system.exception] 
{
	Write-Host  "Error: " $_.Exception.Message
}

Reading an Object (SSE)

The Read-S3Object cmdlet is used retrieve an object from S3. If the object is encrypted in S3, a decrypted object is returned.

$ssefileout   = "YourOutputFile" 
$bucket       = "YourBucketName"
$objectkey    = "YourKeyName" 

try 
{
	Read-S3Object -Region us-west-2 -BucketName $bucket -Key $objectkey -File $ssefileout  
}
catch [system.exception]
{
	Write-Host  "Error: " $_.Exception.Message
}

Copying an Object (SSE)

The Copy-S3Object cmdlet can be used to make a copy of a server-side encrypted object. When copying an object, encryption must be specified explicitly, otherwise the copy will not be encrypted on the server-side. The sample below specifies server-side encryption for the copy.

$bucket         = "YourBucketName"
$objectkey      = "YourKeyName" 
$copyobjectkey  = "YourDestinationKeyName"

try 
{
	Copy-S3Object -Region us-west-2 -BucketName $bucket -Key $objectkey -DestinationBucket $bucket  -DestinationKey $copyobjectkey -ServerSideEncryption AES256
}
catch [system.exception] 
{
	Write-Host  "Error: " $_.Exception.Message
}

Summary

This post showed the options available for encrypting data at rest in S3 when using the Read-S3Object, Write-S3Object, and Copy-S3Object cmdlets to move data around.

For more information, see the Client Side Data Encryption with AWS SDK for .NET and Amazon S3 blog post.