Encryption using Azure Key Vault - C# and PowerShell

In this post I am going to show how you can encrypt strings using Azure Key Vault. Please refer this documentation for the encryption standards followed by Azure Key Vault. So, lets start by creating a new Key Vault in Azure. Once you have done that, generate a new Key which is a Software Key and name it as "NewKey".

The below C# class code will then be able to encrypt and decrypt strings using the Azure Key Vault. It uses Service Principal to access the key vault, so make sure your vault is accessible by the Service Principal you use to authenticate.

 public class KeyVaultDecryptor
    {
        private string vaultAddress;
        private string clientId;
        private string clientSecret;
 
        public KeyVaultDecryptor(string vaultAddress, string clientId, string clientSecret)
        {
            this.vaultAddress = vaultAddress;
            this.clientId = clientId;
            this.clientSecret = clientSecret;
        }
        public string DecryptText(string textToDecrypt)
        {
            var kv = new KeyVaultClient(new KeyVaultClient.AuthenticationCallback(GetToken));
            try
            {
                var key = kv.GetKeyAsync(vaultAddress, "NewKey", null).GetAwaiter().GetResult();
                
                var publicKey = Convert.ToBase64String(key.Key.N);
                using (var rsa = new RSACryptoServiceProvider())
                {
                    var p = new RSAParameters() { Modulus = key.Key.N, Exponent = key.Key.E };
                    rsa.ImportParameters(p);
 
                    // Decrypt
                    var encryptedTextNew = Convert.FromBase64String(textToDecrypt);
                    var decryptedData = kv.DecryptDataAsync(key.Key, JsonWebKeyEncryptionAlgorithm.RSAOAEP, encryptedTextNew).GetAwaiter().GetResult();
                    var decryptedText = Encoding.Unicode.GetString(decryptedData.Result);
 
                    return decryptedText;
                }
            }
            catch (Exception ex)
            {
                return "";
            }
        }
 
        public string EncryptText(string textToEncrypt)
        {
            var kv = new KeyVaultClient(new KeyVaultClient.AuthenticationCallback(GetToken));
            try
            {
                var key = kv.GetKeyAsync(vaultAddress, "NewKey", null).GetAwaiter().GetResult();
                
                var publicKey = Convert.ToBase64String(key.Key.N);
                using (var rsa = new RSACryptoServiceProvider())
                {
                    var p = new RSAParameters() { Modulus = key.Key.N, Exponent = key.Key.E };
                    rsa.ImportParameters(p);
                    var byteData = Encoding.Unicode.GetBytes(textToEncrypt);
 
                    // Encrypt
                    var encryptedText = rsa.Encrypt(byteData, true);
                    string encText = Convert.ToBase64String(encryptedText);
                    return encText;
                }
            }
            catch (Exception ex)
            {
                return "";
            }
        }
 
        async Task<string> GetToken(string authorization, string resource, string scope)
        {
            var authContext = new AuthenticationContext(authorization);
                     ClientCredential clientCred = new ClientCredential(clientId,clientSecret);
            AuthenticationResult result = await authContext.AcquireTokenAsync(resource, clientCred);
 
            if (result == null)
                throw new InvalidOperationException("Failed to obtain the JWT token");
 
            return result.AccessToken;
        }
    }

You can refer to my other blog here to convert this C# code to PowerShell or use the attached zipped module directly in PowerShell or Azure Automation - keyvaultdecryptor

A sample PowerShell code to use Key Vault Encryption in Azure Automation:

[System.Reflection.Assembly]::LoadFrom("C:\Modules\User\KeyVaultDecryptor\KeyVaultDecryptor.dll") | Out-Null ##For Azure Automation that is the path where modules get uploaded$VaultAddress="https://****.vault.azure.net"$ClientId="99b*****************1cb91d"$ClientSecret="Cjl*****************yfTJes0U="$KeyVaultClient = New-Object KeyVaultDecryptor.KeyVaultDecryptor -argumentlist $VaultAddress, $ClientId, $ClientSecret$encrypt = $KeyVaultClient.EncryptText("Administrator@123")$decrypt = $KeyVaultClient.DecryptText($encrypt)