Client-Side Encryption in Java Client Library for Microsoft Azure Storage – Preview

We are excited to announce preview availability of the client side encryption feature in the Azure Storage Java Client Library. This preview enables you to encrypt and decrypt your data inside client applications before uploading to and after downloading from Azure Storage. The feature is available for Blobs, Queues and Tables. We also support integration with Azure Key Vault in order to let you store and manage your keys. We recently made Client-side encryption generally available in the Storage .Net library and now we are happy to provide the same capability in the Java client library as a preview.

Why use client-side encryption?

Client-side encryption is helpful in scenarios where customers want to encrypt the data at source such as encrypting surveillance data from cameras before uploading to Storage. In this scenario, the user controls the keys and the Azure Storage service never sees the keys used for cryptographic operations. You can additionally inspect exactly how the library is encrypting your data to ensure that it meets your standards since the library is open source and available on GitHub. The feature is helpful in scenarios such as encrypting surveillance data from cameras before uploading to Storage.

Benefits of the Java Client Library

We wanted to provide a library that would accomplish the following:

  • Implement Security Best Practices.  This library has been reviewed for its security so that you can use it with confidence. Encrypted data is not decipherable even if the storage account keys are compromised. Additionally, we’ve made it simple and straightforward for users to rotate keys themselves. i.e. multiple keys will be supported during the key rotation timeframe.
  • Interoperability across languages and platforms.  Many users use more than one of our client libraries. Given our goal to use the same technical design across implementations, data encrypted using the .NET library can be decrypted using the Java library and vice versa.  Support for other languages is planned for the future. Similarly, we support cross platform encryption. For instance, data encrypted in the Windows platform can be decrypted in Linux and vice versa.
  • Design for Performance.  We’ve designed the library for both throughput and memory footprint. We have used a technique where there is a fixed overhead so that your encrypted data will have a predictable size based on the original size.
  • Self-contained encryption – Every blob, table entity, or queue message has all encryption metadata stored in either the object or its metadata.  There is no need to get any additional data from anywhere else, except for the key you used.
  • Full blob uploads/ Full and range blob downloads: Upload for blobs such as files like documents, photos and videos that are going to be uploaded in entirety is supported. But sometimes, files like mp3 are downloaded in ranges depending on the part that is to be played. To support this, range downloads are allowed and are entirely taken care of by the SDK.

How to use it?

Using client-side encryption is easy. The client library will internally take care of encrypting data on the client when uploading to Azure Storage, and automatically decrypts it when data is retrieved. All you need to do is specify the appropriate encryption policy and pass it to data upload/download APIs.

 // Create the IKey used for encryption
 RsaKey key = new RsaKey("private:key1" /* key identifier */);
  
 // Create the encryption policy to be used for upload and download.
 BlobEncryptionPolicy policy = new BlobEncryptionPolicy(key, null);
  
 // Set the encryption policy on the request options.
 BlobRequestOptions options = new BlobRequestOptions();
 options.setEncryptionPolicy(policy);
  
 // Upload the encrypted contents to the blob.
 blob.upload(stream, size, null, options, null);
  
 // Download and decrypt the encrypted contents from the blob.
 ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); blob.DownloadToStream(outputStream, null, options, null);

You can find more details and code samples in the Getting Started with Client-Side Encryption for Microsoft Azure Storage article.

Key considerations

  • This is a preview!  It should not be used for production data.  Schema impacting changes can be made and data written with the first preview may not be readable in the GA version.
  • With client side encryption, we support full uploads and full/ range downloads only. As such if you perform operations that update parts of a blob after you have written an encrypted blob, you may end up making it unreadable.
  • Avoid performing a SetMetadata operation on the encrypted blob or specifying metadata while creating a snapshot of an encrypted blob as this may render the blob unreadable. If you must update, then be sure to call the downloadAttributes method first to get the current encryption metadata, and avoid concurrent writes while metadata is being set.

We look forward to your feedback on design, ease of use and any additional scenarios you would like to tell us about.  This will enable us to deliver a great GA release of the library. While some requests for additional functionality may not be reflected in the first release, these will be strongly considered for the future.

Thank you.

Dinesh Murthy
Emily Gerner
Microsoft Azure Storage Team