Azure Storage Account 提供了静态加密,其中密钥支持三种方式:

 

ABOUT ENCRYPTION KEY MANAGEMENT
Key management parameter Microsoft-managed keys Customer-managed keys Customer-provided keys
Encryption/decryption operations Azure Azure Azure
Azure Storage services supported All Blob storage, Azure Files1,2 Blob storage
Key storage Microsoft key store Azure Key Vault or Key Vault HSM Customer's own key store
Key rotation responsibility Microsoft Customer Customer
Key control Microsoft Customer Customer

1 For information about creating an account that supports using customer-managed keys with Queue storage, see Create an account that supports customer-managed keys for queues.
2 For information about creating an account that supports using customer-managed keys with Table storage, see Create an account that supports customer-managed keys for tables.

 

上述三种加密方式在某些文档中也简写为 mmk,cmk,cpk。

直观的区别是:

1. MMK,Microsoft-managed keys,key的存储,替换由微软管理,用户无需关注密钥的维护。 

2. CMK,Customer-managed keys,key由客户自己管理,一般放到key vault中,当需要更换时,在key vault中生成新的key,然后在 storage account的 配置页面修改key即可。

3. CPK, Customer-Provided keys,客户提供的key,这个是最为特殊的,需要在每一个读写请求中(写在代码或着调用api的时候),附加上key的信息,而且storage account中没有任何配置CPK的地方。

关于CPK的信息,请参考:https://docs.microsoft.com/zh-cn/azure/storage/blobs/encryption-customer-provided-keys?WT.mc_id=AZ-MVP-5003757

 

关于CPK的示例代码:

 class Program
    {
       async static Task Main(string[] args)
        {
            string filePath = "/Users/seanyu/Sean-Code/blob-enctyption-by-user-key/blob-encryption-by-user-key/blob-encryption-by-user-key/iothub.json";


            //string connectionString = "DefaultEndpointsProtocol=https;AccountName=seanstorage001;AccountKey=hGp6XxhfFEtpTQfm9rePGOeqZbwa6XFyz1+oUpwaVtLvd3yh9v247xQ7wZ1fU8c0Pw3nc/fMKCI9ySvgKj0EbQ==;EndpointSuffix=core.chinacloudapi.cn";

            string connectionString = "DefaultEndpointsProtocol=https;AccountName=seanstoragetest001;AccountKey=rqsoQkeTKnCMis6Ulu97EK30rsMhZVTEoT+uCvj6Sr2gA2vC0mh3oCqQlam5Ok2qHBHVOCQBJUhryMGY1t+J9w==;EndpointSuffix=core.chinacloudapi.cn";


            string containerName = "sample-container";
            string blobName = "sample-blob";

            string key = "MDEyMzQ1NjcwMTIzNDU2NzAxMjM0NTY3MDEyMzQ1Njc=";
            string keySha256 = "3QFFFpRA5+XANHqwwbT4yXDmrT/2JaLt/FKHjzhOdoE=";



            await  UploadBlobWithClientKey(connectionString,containerName,blobName,filePath,key,keySha256);




        }


        async static Task UploadBlobWithClientKey(string connectionString,
                                         string blobContainerName,
                                         string blobName,
                                         string filePath,
                                         string key,
                                         string keySha256)
        {
            // Create a new customer-provided key.
            // Key must be AES-256.
            var cpk = new CustomerProvidedKey(key);

            // Check the key's encryption hash.
            if (cpk.EncryptionKeyHash != keySha256)
            {
                throw new InvalidOperationException("The encryption key is corrupted.");
            }

            // Specify the customer-provided key on the options for the client.
            BlobClientOptions options = new BlobClientOptions()
            {
                CustomerProvidedKey = cpk
            };

            // Create the client object with options specified.
            BlobClient blobClient = new BlobClient(
                connectionString,blobContainerName,blobName,
                options);

            // If the container may not exist yet,
            // create a client object for the container.
            // The container client retains the credential and client options.
            BlobContainerClient containerClient =
                blobClient.GetParentBlobContainerClient();

            try
            {
                // Create the container if it does not exist.
                await containerClient.CreateIfNotExistsAsync();

                // Upload the data using the customer-provided key.
                await blobClient.UploadAsync(filePath);

                //download to local file
                await blobClient.DownloadToAsync("download.json");

            }
            catch (RequestFailedException e)
            {
                Console.WriteLine(e.Message);
                Console.ReadLine();
                throw;
            }
        }
    }