Created
October 21, 2021 22:41
-
-
Save CodyRichter/a18c293d80c9dd71a3905bf9c44e377f to your computer and use it in GitHub Desktop.
Azure Python API Server Side Encryption Example (CustomerProvidedEncryptionKey)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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