#azure #azure-keyvault
#azure #azure-keyvault
Вопрос:
Я работаю над приложением, в котором я хочу сохранить имя пользователя и пароль для учетной записи службы, которая будет использоваться службой демона.
Идея состоит в том, чтобы предоставить администратору приложения панель мониторинга, где он / она может вводить учетные данные для учетной записи службы, а затем ее можно хранить в безопасном месте.
Я могу подумать о том, чтобы сохранить его в безопасном месте, таком как Azure Vault, и получать его оттуда при необходимости. Однако ключ и секрет — это разные объекты в Azure Vault. Я не могу хранить их где-либо в виде комбинации.
Кто-нибудь делал это раньше? Или есть ли лучшая альтернатива для хранения учетных данных в Azure?
Комментарии:
1. Просто любопытно,
service account
вы говорите об управлении подпиской Azure пользователя от их имени?2. Нет @GauravMantri. Это будут учетные данные для учетной записи службы Dynamics CRM. Учетная запись будет использоваться для обновления объектов в Dynamics CRM через приложение-демон. Кстати, хорошая работа над блогами и статьями, я слежу за вашими блогами 😉
3. Имя пользователя и пароль учетной записи службы будут введены администратором, так в чем же смысл их повторного добавления в хранилище ключей Azure?
4. @HaithamShaddad Я хочу где-нибудь надежно его сохранить. Очевидно, что не в таблице sql 🙂
5. Хранилище ключей Azure предназначено для хранения секретов, которые будут использоваться в приложениях, в Windows, IIS учетная запись службы настраивается на уровне пула приложений, и после этого вам больше не понадобится ее пароль.
Ответ №1:
Вы можете использовать метод, который Azure blob Storage использует для шифрования данных в состоянии покоя (метод конверта):https://learn.microsoft.com/en-us/azure/storage/storage-client-side-encryption
KeyVault имеет возможность оборачивать / разворачивать (шифровать / расшифровывать) симметричные ключи, чтобы вы могли безопасно хранить их вместе с вашими зашифрованными данными.
Вот общие шаги:
- Создайте ключ AES (256 бит, режим CBC) с помощью RNGCryptoServiceProvider
- Зашифруйте данные (учетные данные)
- Сохраните вектор инициализации (IV). Вы можете просто объединить его с массивом байтов зашифрованного текста для последующего извлечения, когда захотите расшифровать — IV не нуждается в защите.
- Оберните (зашифруйте) созданный симметричный ключ AES, используя ключ в KeyVault.
- Храните завернутый ключ AES, IV, зашифрованный текст и версию ключа (GUID в конце URI в KeyVault).
- Убедитесь, что вы предоставили разрешения на перенос / разворачивание в KeyVault для регистрации приложения, созданного в Azure AD. Используйте идентификатор клиента / идентификатор приложения ключ или pfx для авторизации в Azure в getToken().
Вам понадобятся эти пакеты nuget:
Install-Package Microsoft.Azure.KeyVault
Install-Package Microsoft.Azure.KeyVault.Extensions
Install-Package Microsoft.IdentityModel.Clients.ActiveDirectory -Version 2.16.204221202
Получите ссылку на KeyVaultKeyResolver
KeyVaultKeyResolver cloudResolver = new KeyVaultKeyResolver(Utils.GetToken);
// Example GetToken implementation
public class Utils {
// Retrive JWT token to be used for KeyVault access.
internal async static Task<string> GetToken(string authority, string resource, string scope)
{
var authContext = new AuthenticationContext(authority);
// Could use pfx instead
ClientCredential clientCred = new ClientCredential(
ConfigurationManager.AppSettings["clientId"],
ConfigurationManager.AppSettings["clientSecret"]);
AuthenticationResult result = await authContext.AcquireTokenAsync(resource, clientCred);
if (result == null)
throw new InvalidOperationException("Failed to obtain the JWT token.");
return result.AccessToken;
}
}
После того, как у вас есть KeyResolver, вы можете получить iKey для переноса / разворачивания вашего симметричного ключа AES следующим образом…
Перенос / шифрование ключа AES
keyID — это URI из хранилища ключей, а aesKey — это байт [] вашего ключа AES для шифрования:
// Resolve an IKey by Key ID from URI in KeyVault
var keyEncryptionKey = cloudResolver.ResolveKeyAsync(keyId, CancellationToken.None).GetAwaiter().GetResult();
// Take our gen'ed AES Key and wrap (encrypt) it.
Tuple<byte[], string> wrappedKey = keyEncryptionKey.WrapKeyAsync(aeskey, null /* algorithm */, CancellationToken.None).GetAwaiter().GetResult();
Байт[] в кортеже содержит зашифрованные байты симметричного ключа и название используемого алгоритма. Сохраните их как метаданные с вашим зашифрованным текстом.
Развернуть / расшифровать ключ AES
Вызов с использованием того же ключа (важна версия ключа), algoName — это имя алгоритма, используемого для переноса ключа (например, «RSA-OAEP»).
// Retrieve the IKey by Key ID
// Unwrap Key
byte[] aesKey = rsa.UnwrapKeyAsync(wrappedKeyBytes, algoName, CancellationToken.None).GetAwaiter().GetResult();
Другие детали, о которых следует подумать, — это резервное копирование / восстановление ключей и ротация ключей.