System.Security.Cryptography.CryptographicException: «Ключ {00000000-0000-0000-0000-000000000000} не найден в связке ключей».

Я развернул веб-задание (.Net 4.6), которое шифрует некоторые строки URL-адресов и отправляет их клиентам по электронной почте. Я использовал IDataProtector .NET Core для шифрования, и мне пришлось вручную ссылаться на DLL, поскольку webjob .net 4.6 не поддерживал свою библиотеку.

Например, в веб-задании:

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, чтобы открыть страницу соглашения.

Ex:

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} не найден в связке ключей».

Когда я искал ответ, я понял, что могу настроить Data Protection для хранения ключей к хранилищу BLOB-объектов Azure. Это ссылка показывает мне, как сохранить ключи к хранилищу BLOB-объектов Azure.

Вопросов:

  1. Что является лучшим подходом, кроме хранения ключа к хранилищу BLOB-объектов Azure?
  2. Если я на правильном пути, как мне его сохранить?
  3. Как мне настроить тот же параметр для проекта веб-задания, который показан в ссылке, для которой нет Startup.cs?

Помощь очень ценится.




Ответы (1)


Что является лучшим подходом, кроме хранения ключа к хранилищу BLOB-объектов Azure?

На основе предоставленного вами документа мы могли бы хранить ключ в файловой системе, в Azure Redis, хранилище и реестре Azure. Поскольку реестр не поддерживается веб-заданием (веб-приложение Azure). При выборе файловой системы нам также необходимо передать ключи между веб-заданием и вашим веб-приложением. Так что Azure Redis и Azure Storage были бы хорошими подходами.

Если я на правильном пути, как мне его сохранить?

Вот подробные инструкции по хранению ключей в службе хранилища Azure.

Шаг 1, вам необходимо создать учетную запись хранения Azure, если у вас ее нет.

Шаг 2, установите пакет Microsoft.AspNetCore.DataProtection.AzureStorage с помощью NuGet.

Шаг 3, настройте DataProtection, используя следующий код. Нам нужно вызвать метод SetApplicationName и использовать то же имя приложения, что и ваше веб-задание.

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);
    }
}

Как мне настроить тот же параметр для проекта веб-задания, который показан в ссылке, для которой нет Startup.cs?

Шаг 1, вам нужно добавить ссылку на следующие библиотеки DLL.

введите описание изображения здесь

Шаг 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 и использовать то же имя приложения, что и ваше веб-приложение.

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");
person Amor    schedule 13.06.2017
comment
Я так понимаю, если вы добавите уже существующие ключи с именем keys.xml в хранилище BLOB-объектов, они будут прочитаны, а новые не будут созданы? - person gdp; 22.01.2020