System.Security.Cryptography.CryptographicException:'在密钥环中找不到密钥{00000000-0000-0000-0000-000000000000}。

时间:2017-06-12 19:49:04

标签: azure-webjobs data-protection azure-blob-storage asp.net-core-1.1 cryptographicexception

我已经部署了一个 webjob (。Net 4.6),它会加密一些网址字符串并通过电子邮件发送给客户。我使用.NET Core的IDataProtector进行加密,我不得不手动引用DLL,因为webjob .net 4.6不支持它的库。

例如在webjob中:

IDataProtector protector = provider.CreateProtector("myProtector")
http://test.com/Email/Agreement?n=" + protector.Protect(name) + "&a=" + protector.Protect(address)

成为链接

http://test.com/Email/Agreement?n=CfDJ8AAAAAAAAAAAAAAAAAAAAAD96g09022UwEG-GyVftzkm-n2JuL1hmvL5HLyghXliIgJ_N014EBqBFfWjmdA&a=CfDJ8AAAAAAAAAAAAAAAAAAAAAALoq9IuMBZKozhzH3jRaHpyFE1wtXzQK3T_0RNuX9LsSVxPITWgU9ZR21jXLk3YGjt

在电子邮件中。

当客户点击其电子邮件中的url链接时,它会转到我的客户端应用程序的(.Net Core 1.1)控制器来解密url字符串以便弹出协议页。

前:

public EmailController(IDataProtectionProvider provider)
{         
    _protector = provider.CreateProtector("myProtector");
}
public IActionResult Agreement(string n, string a)
{     
    var decryptName = _protector.Unprotect(n);
    var decryptAddress = _protector.Unprotect(a);
}

但是,当我尝试取消保护时,我收到以下错误消息:

  

System.Security.Cryptography.CryptographicException:'在密钥环中找不到密钥{00000000-0000-0000-0000-000000000000}。

当我搜索答案时,我意识到我可以配置数据保护以将密钥存储到Azure Blob存储。这个link向我展示了如何将密钥保存到azure blob存储中。

问题:

  1. 除了将密钥存储到azure blob存储之外,最好的方法是什么?
  2. 如果我走在正确的轨道上,我该如何储存它?
  3. 如何为webjob项目配置相同的设置,如配置中没有Startup.cs的链接所示?
  4. 非常感谢帮助。

1 个答案:

答案 0 :(得分:2)

  

除了将密钥存储到azure blob存储之外,最好的方法是什么?

根据您提供的文档,我们可以将密钥存储在文件系统,Azure Redis,Azure存储和注册表中。由于Web作业(Azure Web App)不支持Registry。如果选择文件系统,我们还需要在Web作业和Web应用程序之间传输密钥。因此Azure Redis和Azure存储将是很好的方法。

  

如果我走在正确的轨道上,我该如何储存它?

以下是如何在Azure存储上存储密钥的详细步骤。

步骤1,如果您没有Azure Storage帐户,则需要创建一个。

步骤2,使用NuGet安装Microsoft.AspNetCore.DataProtection.AzureStorage包。

步骤3,使用以下代码配置DataProtection。我们需要调用SetApplicationName方法并使用与Web作业相同的应用程序名称。

var storageAccount = CloudStorageAccount.Parse("put your azure storage connection string here");
var client = storageAccount.CreateCloudBlobClient();

var container = client.GetContainerReference("key-container");
container.CreateIfNotExistsAsync().GetAwaiter().GetResult();

services.AddDataProtection().SetApplicationName("myapplication")
    .PersistKeysToAzureBlobStorage(container, "keys.xml");

步骤4,在您的控制器中,您可以使用IDataProtectionProvider,如下所示。

public class HomeController : Controller
{
    private IDataProtector _protector;
    public HomeController(IDataProtectionProvider provider)
    {
        _protector = provider.CreateProtector("test-purpose");
    }

    public IActionResult Index()
    {
        string encryptedTExt = _protector.Protect("abcd");
        return Content(encryptedTExt);
    }
}
  

如何为webjob项目配置相同的设置,如配置中没有Startup.cs的链接所示?

步骤1,您需要添加对以下DLL的引用。

enter image description here

步骤2,添加IDataProtector的包装类,如下所示。

public class EncryptService
{
    IDataProtector _protector;

    // the 'provider' parameter is provided by DI
    public EncryptService(IDataProtectionProvider provider)
    {
        _protector = provider.CreateProtector("test-purpose");
    }

    public string Protect(string text)
    {
        return _protector.Protect(text);
    }

    public string Unprotect(string encryptedText)
    {
        return _protector.Unprotect(encryptedText);
    }
}

步骤3,使用ServiceCollection配置数据保护服务。请注意,我们需要调用SetApplicationName方法,使用与Web应用程序相同的应用程序名称

static void Main()
{
    var storageAccount = CloudStorageAccount.Parse("put your azure storage connection string here");
    var client = storageAccount.CreateCloudBlobClient();

    var container = client.GetContainerReference("key-container");
    container.CreateIfNotExistsAsync().GetAwaiter().GetResult();

    var serviceCollection = new ServiceCollection();

    serviceCollection.AddDataProtection().SetApplicationName("myapplication")
        .PersistKeysToAzureBlobStorage(container, "keys.xml"); 

    var services = serviceCollection.BuildServiceProvider();
}

步骤4之后,您可以使用以下代码加密或解密您的数据。

var encryptService = ActivatorUtilities.CreateInstance<EncryptService>(services);
string text = encryptService.Protect("abcd");