A question that seems to keep cropping up is "How to encrypt data in Windows Azure storage?" There some specific factors that determine how (and why) you should do this in Windows Azure.
Before discussing data encryption in Windows Azure, I wanted to recap some background information about Windows Azure storage.
Windows Azure storage
Windows Azure storage includes these three storage types:
- Blob Data
- Table Data
- Queue Data
For the purposes of this article I want to focus on Table and Blob storage. I'm also assuming that the data is going to be used by your Windows Azure application — code running in Worker role or a Web role.
Levels of protection
By default, all data in Windows Azure storage is private. This means that you need a key to get read/write access to the data. Blob storage supports a couple of additional options; you can mark a blob container as "public" so that anyone who knows the URL has read only access, you can also use Shared Access Signatures (SAS) that are special URLs that allow temporary read only access to private blobs without the client needing to know the storage key. For the remainder of this discussion I'm going to assume that we're dealing with private data.
Private (default) - needs a storage key for read/write access
SAS - generates a temporary, anonymous URL
Public - data can be read by anonymous requests
Private - needs a storage key for read/write access
Private - needs a storage key for read/write access
Access to storage keys
To be able to access private data, you need to know the storage key. You can obtain the key from your Windows Azure portal (or by using the Windows Azure Management API). There are in fact two keys: a primary key, and a secondary key. You can use either, but two are provided so that if you want to generate new keys on a regular basis, you can cycle them and ensure that your applications have uninterrupted access to your data.
Each Windows Azure storage account has it's own keys, and you can create a limited number of storage accounts with a single Windows Azure subscription.
If you have a valid key, you have read/write access to your Windows Azure storage from within a Windows Azure role, or from outside (for example, from an on-premises application).
If you are not encrypting data in your Windows Azure storage, you should be aware of the following vulnerabilities and take steps to minimize the risk of someone gaining unauthorized access to your data.
If access to your portal is compromised (someone discovers the Live ID user name and password, or a Management API key), then the storage access keys are discoverable, and all your data is accessible. You should bear in mind that the portal Administrator, all the portal Co-admins, and anyone with a copy of a portal Management API key will have full access to your portal, your storage keys, and your data. There is no granular permissions system in the Windows Azure portal.
You must carefully manage access to your Windows Azure portal; limit access to those who need it, make sure that passwords and Management API keys are changed frequently, and that you enforce strict password policies. For most organizations it will make sense to have multiple Windows Azure subscriptions, with different people having access to each one. For example, you might have Production, Test, and Development subscriptions.
The source code of any application that accesses private Windows Azure storage will also include the storage key — typically the key is placed in a configuration file. This implies that anyone with access your source code will be able to discover the keys and therefore will be able to access your data.
You should carefully control who has access to the storage keys. Ideally, you should use deployment scripts that substitute the storage key values in the application's configuration files in a secure build/deployment scenario. Developers and testers should only have storage keys that enable them to access test data and not production data.
If there is a hardware failure in a Windows Azure datacenter, it may be that the hard disk with your data is replaced and the old one disposed of. In this case it's theoretically possible that an unauthorized person might obtain this disk.
However, hardware disposal is governed by Microsoft's Global Foundation Services policy that details procedures for wiping or destroying drives and securely disposing of hardware from Windows Azure datacenters. These policies are designed to minimize the risks of anyone obtaining hardware containing data. See: http://blogs.technet.com/b/gfs/archive/2009/05/27/securing-microsoft-s-cloud-infrastructure.aspx.
As an additional level of security, you may want to encrypt the data in your Windows Azure storage tables and blobs, so that if someone gained unauthorized access to your portal, your storage keys, or the hard disks that contained your data, then they wouldn't be able to decrypt your data.
Options for encrypting data
- Use symmetric key encryption - you need a single key to encrypt/decrypt data.
- Use asymmetric key encryption - encrypt with public key, decrypt with private key.
Whichever encryption technique is used, your Windows Azure code in the web or worker role will need access to the key. Therefore the key must be stored somewhere in Windows Azure - in a blob, in the code or a configuration file, or in the certificate store.
The vulnerabilities associated with an unauthorized person being able to access and decrypt data from your Windows Azure storage are different from the vulnerabilities associated with simple, unauthorized access.
If the portal is compromised because someone discovers your Windows LiveID credentials or Management API key, then anything stored in a blob or the certificate store is accessible and they will be able to access your encryption key and decrypt your data. However, it doesn't appear to be possible to access the code and configuration files associated with a deployed application in Windows Azure, so storing your private encryption keys in an App.config or Web.config file appears to be the best option.
There are two exceptions to bear in mind: first, the ServiceConfiguration.csfg file is accessible to anyone with access to your portal, so don’t store encryption keys here; second, all your code and configuration files are accessible if you have configured Remote Desktop Access: however, Remote Desktop Access must be configured at deploy time, you can't configure it after you have deployed the application, so you should not enable Remote Desktop Access if you are concerned about unauthorized access to your data.
If someone obtained the physical disk that contains your data because they could easily read any encryption keys in configuration files or blobs, and the encrypted data; in this case you must rely on Microsoft's procedures for protecting the Windows Azure datacenters and for wiping and destroying disks that have been removed from a Windows Azure datacenter.
If you choose to store your encryption key in a Web.config or App.config file, you must also address the issue of how to protect the encryption key before it is deployed to Windows Azure. Anyone with access to the source code will have access to the encryption keys and therefore to the encrypted data. Ideally, your build and deployment process should replace any test or development encryption keys with production keys just prior to deployment in a secure build environment. This way, you can limit who has access to the production encryption keys.
A final issue to consider is that a developer could inadvertently (or maliciously) deploy code that accesses your encrypted data and exposes in way that you didn’t intend. If your build and deployment process replaces test or development encryption keys with production encryption keys, then any deployed code could still access the decryption keys at run time and access the encrypted data. There are a number of steps you should take to mitigate this risk:
- Ensure that all code changes are traceable to individuals.
- Ensure that all code is reviewed before it is deployed.
Writing Secure Code for Windows Azure
This blog post has focused specifically on issues relating to Windows Azure storage and encryption; for a more general discussion of writing secure applications for Windows Azure see "Security Best Practices For Developing Windows Azure Applications."
You should also take a look at the Security Development Lifecycle (SDL).
If you decide to encrypt your data in Windows Azure storage, then to minimize the risk of someone gaining unauthorised access to your encrypted data, you should store the encryption key in the Web.config or App.config file in your application. However, you should make sure that your development and deployment processes are designed to minimize the risk of someone discovering your encryption keys before you deploy your application to Windows Azure.