Skip to content

Instantly share code, notes, and snippets.

@CodyRichter
Created October 21, 2021 22:41
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save CodyRichter/a18c293d80c9dd71a3905bf9c44e377f to your computer and use it in GitHub Desktop.
Save CodyRichter/a18c293d80c9dd71a3905bf9c44e377f to your computer and use it in GitHub Desktop.
Azure Python API Server Side Encryption Example (CustomerProvidedEncryptionKey)
import hashlib
import base64
from azure.storage.blob import CustomerProvidedEncryptionKey, ContainerClient
'''
Overview:
After looking to switch to Azure blob storage from AWS s3, one of the features that was missing was the ability to easily encrypt data
on the server side with client-provided keys.
AWS Reference: https://docs.aws.amazon.com/AmazonS3/latest/userguide/ServerSideEncryptionCustomerKeys.html
Although Azure claimed to have this ability, I was unable to find any examples of server side encryption using the Azure python API.
The major difference between AWS s3 SSE-C and Azure blob storage server-side encryption is that Azure requires you to generate your
own sha256 hash of the AES-256 key that is provided.
After some pain with encodings, I was able to come up with this working example. I hope that this example helps someone who is
looking to use server-side encryption on Azure from Python.
'''
connection_string = '<Redacted>'
container_name = 'your_container_name'
target_blob_name = 'your_target_file_name.txt'
# This is the AES256 key and the SHA256 hash of the key
key = b'32byteslongsecretkeyshallbegiven'
key_hash = hashlib.sha256(key).hexdigest()
# This is the most critical line of the file, and what makes the process not as straight forward as it seems.
# The key_hash variable is a python string that represents a hex encoding. We need to specially base64
# encode the key hash and treat it as a hex string and NOT as a typical python string. If you just do the normal
# base64.b64encode(key_hash), you will get the wrong hash and an error from the API.
key_hash_b64 = base64.b64encode(bytes.fromhex(key_hash))
# We can now base64 encode the encryption key normally.
key_b64 = base64.b64encode(key)
# Generate the CustomerProvidedEncryptionKey and the ContainerClient
# Note that we must pass a python string to the constructor and not bytes.
cpk = CustomerProvidedEncryptionKey(key_b64.decode('utf-8'), key_hash_b64.decode('utf-8'))
container_client = ContainerClient.from_connection_string(
connection_string,
container_name=container_name,
cpk=cpk # Set the CPK here. Alternatively, you can include it as an argument to upload_blob instead.
)
# Now you can upload your blob with server-side encryption!
container_client.upload_blob(
data='Hello World!! I am encrypted', name=target_blob_name, overwrite=True
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment