System.Security.Cryptography.CryptographicException: "Ключ {00000000-0000-0000-0000-000000000000} не был найден в кольце для ключей."
Я развернул веб-задание (.Net 4.6), которое шифрует некоторые строки URL-адресов и отправляет их клиентам по электронной почте. Я использовал IDataProtector.NET Core для шифрования, и мне пришлось вручную ссылаться на 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} не был найден в кольце для ключей."
Когда я искал ответ, я понял, что могу настроить защиту данных для хранения ключей в хранилище BLOB-объектов Azure. Эта ссылка показывает, как сохранить ключи в хранилище BLOB-объектов Azure.
Вопросы:
- Как лучше всего хранить ключи от хранилища BLOB-объектов Azure?
- Если я на правильном пути, как мне его сохранить?
- Как настроить тот же параметр для проекта webjob, который показан в ссылке, в которой нет файла Startup.cs для настройки?
Помощь очень ценится.
1 ответ
Как лучше всего хранить ключи от хранилища BLOB-объектов Azure?
На основании предоставленного вами документа мы можем хранить ключ в файловой системе, Azure Redis, хранилище Azure и реестре. Поскольку реестр не поддерживается веб-заданием (Azure Web App). При выборе файловой системы нам также необходимо передать ключи между веб-заданием и вашим веб-приложением. Так что 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);
}
}
Как настроить тот же параметр для проекта webjob, который показан в ссылке, в которой нет файла 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");