【问题标题】:How do you decrypt blobs with Azure KeyVault keys in Azure.Storage v12如何在 Azure.Storage v12 中使用 Azure KeyVault 密钥解密 blob
【发布时间】:2021-07-18 04:51:39
【问题描述】:

我们的代码目前正在使用旧的 Microsoft.WindowsAzure.Storage 库来访问 Azure 中的 blob 存储。我正在尝试使用新的 v12 Azure.Storage.Blobs 库来替换旧的库,但是我不知道如何解密/加密 blob。 MS 文档 (https://docs.microsoft.com/en-us/azure/storage/blobs/storage-encrypt-decrypt-blobs-key-vault?tabs=dotnet) 很有帮助地说 v12 代码 sn-ps 尚未准备好,因此没有代码示例。

旧代码是这样的:

var tokenProvider = new AzureServiceTokenProvider();
var cloudResolver = new KeyVaultKeyResolver(
    new KeyVaultClient.AuthenticationCallback(_tokenProvider.KeyVaultTokenCallback));
var encryptionThingy = await cloudResolver.ResolveKeyAsync(<Key Vault URL> + "/keys/" + <key name>, CancellationToken.None);
var policy = new BlobEncryptionPolicy(encryptionThingy, cloudResolver);
var options = new BlobRequestOptions() { EncryptionPolicy = policy };
await <ICloudBlob Instance>.DownloadToStreamAsync(<stream>, null, options, null);

到目前为止,我在这里得到的新代码:

var azureKeys = new KeyClient(new Uri(<key vault url>), new DefaultAzureCredential());
var encKey = azureKeys.GetKey(<key name>);
ClientSideEncryptionOptions encryptionOptions = new ClientSideEncryptionOptions(ClientSideEncryptionVersion.V1_0)
{
    KeyEncryptionKey = (IKeyEncryptionKey)key
};
var bsClient = new BlobServiceClient(cStr, new SpecializedBlobClientOptions() { ClientSideEncryption = encryptionOptions });
var containerClient = new BlobContainerClient(cStr, containerName);
bClient = containerClient.GetBlobClient(<blob name>);

当然这会引发异常,因为 KeyVaultKey 无法转换为 IKeyEncryptionKey。所以我的问题是

  1. 能否轻松将密钥转换为 IKeyEncryptionKey,如何转换?
  2. 能否从 Azure SDK 轻松检索密钥解析器?如何实现?

我假设有一些方法可以做到这一点,而不涉及创建我们自己的接口实现,但 MS 以其无限的智慧认为不适合将这几行添加到他们的文档中。

【问题讨论】:

    标签: c# encryption azure-keyvault azure-blob-storage


    【解决方案1】:

    我为你写了一个简单的演示。只需尝试下面的 C# 控制台应用程序,了解如何使用 azure KeyVault 进行 azure blob 客户端加密:

    using System;
    
    using Azure.Identity;
    using Azure.Security.KeyVault.Keys.Cryptography;
    using Azure.Storage;
    using Azure.Storage.Blobs;
    using Azure.Storage.Blobs.Specialized;
    
    namespace BlobEncyptionWithBlob
    {
        class Program
        {
            
            static void Main(string[] args)
            {
                string keyVaultName = "";
                string keyName = "";
                string kvUri = "https://" + keyVaultName + ".vault.azure.net/keys/" + keyName;
    
    
                string storageConnStr = "";
                string containerName = "";
                string encyptBlob = "encypt.txt";
                string localblobPath = @"C:\Users\Administrator\Desktop\123.txt";
                string localblobPath2 = @"C:\Users\Administrator\Desktop\123-decode.txt";
    
                //Below is to use recommended OAuth2 approach
                //string clientID = "<OAuth Client ID>";
                //string clientSecret = "<OAuth Secret>";
                //string tenant = "<OAuth Tenant ID>";
                //var cred = new ClientSecretCredential(tenant, clientID, clientSecret);
    
                //This is what you use to directly replace older AppAuthentication
                var cred = new DefaultAzureCredential();
          
                CryptographyClient cryptoClient = new CryptographyClient(new Uri(kvUri), cred);
                KeyResolver keyResolver = new KeyResolver(cred);
    
                ClientSideEncryptionOptions encryptionOptions = new ClientSideEncryptionOptions(ClientSideEncryptionVersion.V1_0)
                {
                    KeyEncryptionKey = cryptoClient,
                    KeyResolver = keyResolver,
                    KeyWrapAlgorithm = "RSA-OAEP"
    
                };
    
                BlobClientOptions options = new SpecializedBlobClientOptions() { ClientSideEncryption = encryptionOptions };
    
    
                var blobClient = new BlobServiceClient(storageConnStr,options).GetBlobContainerClient(containerName).GetBlobClient(encyptBlob);
    
                //upload local blob to container
                blobClient.Upload(localblobPath);
    
                //If you want to modify the meta data you have to copy the exisiting meta, think there is a bug in the library that will wipe out the encryptiondata metadata if you write your own meta
                var myMeta = new Dictionary<string, string>();
                myMeta.Add("comment", "dis file is da shiznit");
                foreach (var existingMeta in blobClient.GetProperties().Value.Metadata)
                {
                    if (!myMeta.ContainsKey(existingMeta.Key))
                    {
                        myMeta.Add(existingMeta.Key, existingMeta.Value);
                    }
                }
                blobClient.SetMetadata(myMeta);
    
                //Download from container to see if it is decided
                blobClient.DownloadTo(localblobPath2);
    
            }
        }
    }
    

    结果:

    我的本​​地.txt文件内容:

    上传到 blob 及其内容,已加密:

    再次下载到本地,内容已解码:

    【讨论】:

    • 您的代码在创建 ClientSecretCredential 时使用了新的 OAuth2 方法。要真正替换我的旧代码,我必须使用 DefaultAzureCredential。 IE - 您的凭据应使用以下命令创建:var appCred = new DefaultAzureCredential();。这个文档对我很有帮助:docs.microsoft.com/en-us/dotnet/api/overview/azure/….
    • @lan 我假设你关注的是ClientSideEncryptionOptions,我只是在这里使用ClientSecretCredential 进行演示。无论如何,如果我的帖子有帮助,您可以接受它作为答案吗?
    • 我已经编辑了你的答案,以便更恰当地回答这个问题。
    猜你喜欢
    • 2021-06-01
    • 2021-11-24
    • 1970-01-01
    • 2022-01-27
    • 2018-08-17
    • 2021-11-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多