0
votes

I have a scenario where I need to take a blob (upwards of multiple GB in size) from one storage account and copy + encrypt it and put it in another blob storage account. It looks like I could do this by setting a BlobEncryptionPolicy and doing StartCopyAsync. However, that requires Key Vault access and the system that will download this encrypted blob will not have access to that vault. We also do not have access to the recipient's private key (because it's theirs, not ours), so we can't just load their .pfx into our vault.

With that off the table I'm not sure what other option there is beyond: 1. Download the blob to the cloud service's filesystem (or perhaps to an azure file storage account) and encrypt it. 2. Upload the encrypted file to the destination blob storage account. 3. Delete the encrypted file from the share.

Are there other approaches that may work in this case?

1

1 Answers

1
votes

Are there other approaches that may work in this case?

As far as I know, azure storage has two Encryption.

One is server-side encryption, Azure Storage automatically encrypts your data prior to persisting to storage and decrypts prior to retrieval. The encryption, decryption, and key management are totally transparent to users.

By using this way, azure will encrypt your data when uploading to the storage server. It will decrypt the data when the user want to access it.

You could directly enable it in the portal as below:

enter image description here

Another one is client-side Encryption, we could use azure key value or local key value to encrypt the data.

So if we want to use client-side Encryption, we need download the file from the blob then encrypt it and upload it to another storage account.

This is the client-side Encryption without use azure key-value way.

We could create a local rsa key to encrypt it, then you could store this rsa key at local.

If you want to decrypt the encrypted contents from the blob, you could use the rsa key.

More details, you could refer to below sample:

LocalResolver.cs(Used to store the ikey)

 public class LocalResolver : IKeyResolver
    {
        private Dictionary<string, IKey> keys = new Dictionary<string, IKey>();

        public void Add(IKey key)
        {
            keys[key.Kid] = key;
        }

        public async Task<IKey> ResolveKeyAsync(string kid, CancellationToken token)
        {
            IKey result;

            keys.TryGetValue(kid, out result);

            return await Task.FromResult(result);
        }
    }

Upload encrypt blob and download decrypt blob :

  static void Main(string[] args)
        {
            Console.WriteLine("Blob encryption sample");

            // Retrieve storage account information from connection string
            // How to create a storage connection string - https://azure.microsoft.com/en-us/documentation/articles/storage-configure-connection-string/
            CloudStorageAccount storageAccount = CloudStorageAccount.Parse(
            "DefaultEndpointsProtocol=https;AccountName=brandofirststorage;AccountKey=4j8EjQzNtkzQ22Xp3NZcxvJz/+PUOOOQRTSZ9TieQg1lYM6eBCDpKoJgMcNWoG6p1GjMQhkYrxPKRBralzQoZA==;EndpointSuffix=core.windows.net");

            CloudBlobClient client = storageAccount.CreateCloudBlobClient();
            CloudBlobContainer container = client.GetContainerReference("example");


                container.CreateIfNotExists();
                int size = 5 * 1024 * 1024;
                byte[] buffer = new byte[size];

                Random rand = new Random();
                rand.NextBytes(buffer);

                CloudBlockBlob blob = container.GetBlockBlobReference("test");

                // Create the IKey used for encryption.
                RsaKey key = new RsaKey("private:key1");

                // Create the encryption policy to be used for upload.
                BlobEncryptionPolicy uploadPolicy = new BlobEncryptionPolicy(key, null);

                // Set the encryption policy on the request options.
                BlobRequestOptions uploadOptions = new BlobRequestOptions() { EncryptionPolicy = uploadPolicy };

                Console.WriteLine("Uploading the encrypted blob.");

                // Upload the encrypted contents to the blob.
                using (MemoryStream stream = new MemoryStream(buffer))
                {
                    blob.UploadFromStream(stream, size, null, uploadOptions, null);
                }





                // Download the encrypted blob.
                // For downloads, a resolver can be set up that will help pick the key based on the key id.
                LocalResolver resolver = new LocalResolver();
                resolver.Add(key);

                BlobEncryptionPolicy downloadPolicy = new BlobEncryptionPolicy(null, resolver);

                // Set the decryption policy on the request options.
                BlobRequestOptions downloadOptions = new BlobRequestOptions() { EncryptionPolicy = downloadPolicy };

                Console.WriteLine("Downloading the encrypted blob.");

                // Download and decrypt the encrypted contents from the blob.
                using (MemoryStream outputStream = new MemoryStream())
                {
                    blob.DownloadToStream(outputStream, null, downloadOptions, null);
                }

                Console.WriteLine("Press enter key to exit");
                Console.ReadLine();


        }

Besides, a copy blob operation simply copies the bytes from source to target in the server side. So it will not encrypt it when the server copy the file.