Azure KeyVault used for Blockchain data encryption with Java / Spring (1)


Shared Blockchain privacy concerns

For the project I'm now developing, I need a way to safely encrypt lot of data. Multiple organisations are sharing the same blockchain network, only that it is not allowed for everyone to share data with everybody, but data is shared only in enclaves. Let's say you have manufacturer A with it's customers, manufacturer B with it's customers and manufacturer C with it's own customers. It's not allowed for manufacturer B to see data from manufacturer A, but it's mandatory for manufacturer A and it's customers to have access to the same blockchain stored data.
One way to approach this (and the cleanest approach) would be to deploy separate blockchain networks for each enclave. Unfortunately this is not an option due to the complexity and costs required to deploy and manage lot of networks. Also, it would not accommodate smaller actors, who could not afford the costs to deploy a network just for them. 

The next best option would be to use Parity Private Transaction approach, and encrypt contract data using the official Parity implementation - . I've used this for one of the projects I developed last year, and was like "never again !". Their implementation is buggy, fragile and difficult to work with. In 2019, Private Transactions lacked support in web3j due to its novelty, so we first had to extend web3j to support it. Only to find out that we run in all sorts of issues, such as gas limitations due to the costly encryption operations that run on blockchain, difficult error handling due to the many processing layers and many many others. It was not a path I would take again happily.

So, I decided to encrypt the data myself out of the blockchain network and store it encrypted in blockchain. Not the best choice, security risks involved, leaked key and many, but the only viable approach. I chose to use Azure KeyVault for data encryption. I liked the fact that the encryption keys never leave Azure KeyVault, so I don't have to care about protecting those. The encryption key is created inside the KeyVault and you can use it encrypt and decrypt data and the whole process happens inside the KeyVault. You can assign granular rights to a key for every actor involved. And even nicer, server authentication against the KeyVault can be done using Managed Identities for Azure, so you don't have to maintain authentication keys by hand.

One of the not so nice things about KeyVault (at least from my perspective), is the way the documentation is structured. It seems to be just a bunch of articles that had grown organically over time in the same webpage, with no real care to keep things consistent. Google Cloud is years ahead here ! Maybe it would be easier if I would use .NET instead, but for Java I find it to be quite messy. Had to google and stackoverflow quite a lot. Also, another not so nice surprise was finding out that there is quite a big limitation on the size of the data that can be encrypted using KeyVault Encrypt operation ( What Microsoft says is "[...]the data size is dependent on the target key and the encryption algorithm to be used.". In practice, for the RSA* encryption algorithm, supported by KeyVault, you'll find out that the data size is way too limited to be of practical use for real world data encryption. What Microsoft suggests is to use an RSA* asymmetric key stored inside KeyVault just to encrypt a symmetric key, that you are going to use outside of KeyVault to encrypt/decrypt your data. Disclaimer: I have no real experience in cryptography, so it could be that my expectations to encrypt the whole business data inside KeyVault using an asymmetric key to just not be a realistic one. Using a KeyVault managed RSA asymmetric key to encrypt a symmetric key, and store the encrypted symmetric key inside my application wa good enough for me, so I chose to go with this.

For the actual Java Spring implementation, see here -