Use Azure Key Vault to store username and password

I am working on an application where I want to save the username and password for the service account that will be used by the daemon service.

The idea is to give the application administrator a dashboard where he can enter credentials for the service account, and then it can be stored somewhere safe.

I might consider storing it in a safe place, such as in Azure Vault, and getting it from there when necessary. However, the key and secret are different objects in Azure Vault. I cannot store them somewhere in combination.

Has anyone done this before? Or is there a better alternative for storing credentials in Azure?

+5
source share
1 answer

You can use the technique used by Azure storage to encrypt data at rest (envelope method): https://docs.microsoft.com/en-us/azure/storage/storage-client-side-encryption

KeyVault has the ability to Wrap / Unwrap (encrypt / decrypt) symmetric keys so that they are safe to store along with your encrypted data.

Here are the basic steps:

  • Generate an AES key (256 bit, CBC mode) using RNGCryptoServiceProvider
  • Encrypt data (credentials)
  • Save initialization vector (IV). You can simply concatenate it with a byte array of ciphertext for later searching, when you want to decrypt - IV does not need protection.
  • Wrap (encrypt) the AES genetic symmetric key with the KeyVault key.
  • Save Wraped AES Key, IV, CipherText and Key Version (GUID at the end of the URI in KeyVault).
  • Make sure you grant Wrap / Unwrap permissions to KeyVault to register applications created in Azure AD. Use the client ID / application ID + key or pfx to log in to Azure in GetToken ().

You will need these nuget packages:

Install-Package Microsoft.Azure.KeyVault Install-Package Microsoft.Azure.KeyVault.Extensions Install-Package Microsoft.IdentityModel.Clients.ActiveDirectory -Version 2.16.204221202 

Get a link to 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; } } 

Once you have KeyResolver, you can get the IKey for the Wrap / Unwrap symmetric AES key as follows:

Wrap / Encrypt AES Key

The key identifier is the URI from Key Vault, and aesKey is the byte [] of your AES key for encryption:

 // 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(); 

Byte [] in Tuple contains the encrypted bytes of the symmetric key and the name of the algorithm used. Save them as metadata with your ciphertext.

Expand / Decrypt AES Key

A call using the same key (the key version matters), algony_name is the name of the algorithm used to wrap the key (for example, "RSA-OAEP").

 // Retrieve the IKey by Key ID // Unwrap Key byte[] aesKey = rsa.UnwrapKeyAsync(wrappedKeyBytes, algoName, CancellationToken.None).GetAwaiter().GetResult(); 

Other details to consider are key backup / restore and key rotation.

+4
source

Source: https://habr.com/ru/post/1258509/


All Articles