0

I'm encrypting a string using Azure CLI:

az keyvault key encrypt --id "https://myhsmtest.managedhsm.azure.net/keys/aes256/1234aed127f8009e15d6c3a883b91f21" --algorithm A256GCM --value "123" --data-type plaintext 

This returns me a JSON:

{ "aad": null, "algorithm": "A256GCM", "iv": "8f7f424c8548bac26c947bfd", "kid": "https://myhsmtest.managedhsm.azure.net/keys/aes256/1234aed127f8009e15d6c3a883b91f21", "result": "PtLm", "tag": "e96de8eee3e194529095ef196f54cef0" } 

Now I'd like to decrypt this in C#:

var json = "{\n \"aad\": null,\n \"algorithm\": \"A256GCM\",\n \"iv\": \"8f7f424c8548bac26c947bfd\",\n \"kid\": \"https://myhsmtest.managedhsm.azure.net/keys/aes256/1234aed127f8009e15d6c3a883b91f21\",\n \"result\": \"PtLm\",\n \"tag\": \"e96de8eee3e194529095ef196f54cef0\"\n}"; var jsonDocument = JsonDocument.Parse(json); var cipherText = jsonDocument.RootElement.GetProperty("result").GetString(); var iv = jsonDocument.RootElement.GetProperty("iv").GetString(); var tag = jsonDocument.RootElement.GetProperty("tag").GetString(); var cipherTextBytes = Convert.FromBase64String(cipherText); var ivBytes = Convert.FromBase64String(iv); var tagBytes = Convert.FromBase64String(tag); var keyVaultUrl = "https://myhsmtest.managedhsm.azure.net"; var credential = new DefaultAzureCredential(); var client = new KeyClient(vaultUri: new Uri(keyVaultUrl), credential); var cryptographyClient = client.GetCryptographyClient("aes256", "1234aed127f8009e15d6c3a883b91f21"); DecryptParameters decryptParameters = DecryptParameters.A256GcmParameters(ciphertext: cipherTextBytes, iv: ivBytes, authenticationTag: tagBytes); var result = cryptographyClient.Decrypt(decryptParameters); 

It fails with the following error:

Azure.RequestFailedException: HSM Error: Invalid input data/params (Activity ID: e947a2ec-9f6d-11ef-846b-000d3a278b83) Status: 400 (Bad Request) ErrorCode: BadParameter Content: {"error":{"code":"BadParameter","message":"HSM Error: Invalid input data/params (Activity ID: e947a2ec-9f6d-11ef-846b-000d3a278b83)"}} Headers: x-ms-server-latency: REDACTED Cache-Control: no-cache X-Content-Type-Options: REDACTED x-ms-request-id: e947a2ec-9f6d-11ef-846b-000d3a278b83 Strict-Transport-Security: REDACTED Content-Security-Policy: REDACTED X-Frame-Options: REDACTED Content-Type: application/json; charset=utf-8 Content-Length: 134 at Azure.Security.KeyVault.KeyVaultPipeline.SendRequest(Request request, CancellationToken cancellationToken) at Azure.Security.KeyVault.KeyVaultPipeline.SendRequest[TContent,TResult](RequestMethod method, TContent content, Func`1 resultFactory, CancellationToken cancellationToken, String[] path) at Azure.Security.KeyVault.Keys.Cryptography.RemoteCryptographyClient.Decrypt(DecryptParameters parameters, CancellationToken cancellationToken) at Azure.Security.KeyVault.Keys.Cryptography.RemoteCryptographyClient.Azure.Security.KeyVault.Keys.Cryptography.ICryptographyProvider.Decrypt(DecryptParameters parameters, CancellationToken cancellationToken) at Azure.Security.KeyVault.Keys.Cryptography.CryptographyClient.Decrypt(DecryptParameters decryptParameters, CancellationToken cancellationToken) ... 

If I encrypt a string in C# and decrypt it right away using EncryptResult.Ciphertext, EncryptResult.Iv and EncryptResult.AuthenticationTag, it works well. But when I'm using JSON from CLI in C# - I have this error.

If I use values from this JSON in CLI (az keyvault key decrypt), it also works well.

So I suppose that I'm not doing decoding of result, iv and tag from JSON to bytes[] well, but I don't get what is exactly wrong.

3
  • IV and tag seem to be hex encoded and not Base64. Commented Nov 10, 2024 at 15:01
  • @Topaco you're right! Thank you! Commented Nov 10, 2024 at 17:12
  • @dotdev check the below answer. Commented Nov 11, 2024 at 6:59

1 Answer 1

0

Azure Managed HSM: Decrypt in C# using encryption result from Azure CLI.

In my environment, I encrypted the azure Managed HSM key same as your Azure CLI command:

az keyvault key encrypt --id "https://xxx.managedhsm.azure.net/keys/Venkatesan326/xxxxxx" --algorithm A256GCM --value "this is plaintext" --data-type plaintext This command is in preview and under development. Reference and support levels: https://aka.ms/CLI_refstatus { "aad": null, "algorithm": "A256GCM", "iv": "40f91e6934c5af97b6d18ec6", "kid": "https://xxx.managedhsm.azure.net/keys/Venkatesan326/xxx", "result": "xxxx=", "tag": "ac077axxxxbd15af346" } 

enter image description here

I agree with Topaco's comment it should be in hexa encoded. you can use the below code which decrypt the encryption result from azure cli using C#.

Code:

using Azure.Identity; using Azure.Security.KeyVault.Keys; using Azure.Security.KeyVault.Keys.Cryptography; using System; using System.Text; public class AzureHSMDecryptionExample { public static void Main(string[] args) { // Updated JSON response from Azure CLI (adjust values accordingly) var json = "{\n \"aad\": null,\n \"algorithm\": \"A256GCM\",\n \"iv\": \"4xxxxx\",\n \"kid\": \"https://xxxx.managedhsm.azure.net/keys/Venkatesan326/xxxx\",\n \"result\": \"xxxx\",\n \"tag\": \"xxxx\"\n}"; // Parse the JSON response var jsonDocument = System.Text.Json.JsonDocument.Parse(json); var cipherText = jsonDocument.RootElement.GetProperty("result").GetString(); var iv = jsonDocument.RootElement.GetProperty("iv").GetString(); var tag = jsonDocument.RootElement.GetProperty("tag").GetString(); byte[] ivBytes = HexStringToByteArray(iv); byte[] tagBytes = HexStringToByteArray(tag); byte[] cipherTextBytes = Convert.FromBase64String(cipherText); // KeyVault URI and credentials var keyVaultUrl = "https://xxx.managedhsm.azure.net"; var credential = new DefaultAzureCredential(); var client = new KeyClient(new Uri(keyVaultUrl), credential); var cryptographyClient = client.GetCryptographyClient("Venkatesan326", "xxxx"); // Create the decrypt parameters using the A256GcmParameters method var decryptParameters = DecryptParameters.A256GcmParameters( ciphertext: cipherTextBytes, iv: ivBytes, authenticationTag: tagBytes ); // Perform decryption try { var result = cryptographyClient.Decrypt(decryptParameters); string decryptedValue = Encoding.UTF8.GetString(result.Plaintext); Console.WriteLine("Decrypted Value: " + decryptedValue); } catch (Exception ex) { Console.WriteLine($"Decryption failed: {ex.Message}"); } } public static byte[] HexStringToByteArray(string hex) { int length = hex.Length / 2; byte[] bytes = new byte[length]; for (int i = 0; i < length; i++) { bytes[i] = Convert.ToByte(hex.Substring(i * 2, 2), 16); } return bytes; } } 

Output:

Decrypted Value: this is plaintext 

enter image description here

Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.