You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Azure CLI加密字符串后,在C#中调用Azure Managed HSM解密失败的问题排查

Azure CLI加密字符串后,在C#中调用Azure Managed HSM解密失败的问题排查

我来帮你排查这个问题!你遇到的核心矛盾很清晰:用Azure CLI加密得到的结果,CLI自己能解密,C# SDK自己加密解密也没问题,但CLI加密的结果拿到C#里就报错。你猜的方向完全没错——问题确实出在JSON里的iv、result、tag的解码方式上。

问题定位

先看你用到的Azure CLI加密命令:

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

它返回的JSON里,iv、result、tag都是十六进制字符串,而不是Base64字符串!但你在C#代码里用了Convert.FromBase64String()去转换这些值,这就导致生成的字节数组完全错误,HSM自然会返回"Invalid input data/params"的错误。

对比一下就能明白:C# SDK的EncryptResult返回的Ciphertext、Iv、AuthenticationTag都是Base64编码的字节数组,所以你用Base64转换没问题;但Azure CLI的输出是十六进制格式,这就是两者的关键差异。

解决方案

把十六进制字符串转换成字节数组即可。.NET 5及以上版本提供了Convert.FromHexString()方法可以直接用,如果你用的是更低版本,也可以自己实现一个十六进制转字节的工具方法。

修改后的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();

// 关键修改:用十六进制转换替代Base64转换
var cipherTextBytes = Convert.FromHexString(cipherText);
var ivBytes = Convert.FromHexString(iv);
var tagBytes = Convert.FromHexString(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);

// 输出解密后的明文
var plaintext = Encoding.UTF8.GetString(result.Plaintext);
Console.WriteLine(plaintext); // 应该输出"123"

低版本.NET兼容方案

如果你的项目基于.NET Framework或者.NET Core 3.1及以下,可以用这个自定义的十六进制转字节数组方法:

public static byte[] HexToByteArray(string hex)
{
    if (hex.Length % 2 != 0)
        throw new ArgumentException("Hex string must have even length.");
    
    byte[] bytes = new byte[hex.Length / 2];
    for (int i = 0; i < hex.Length; i += 2)
    {
        bytes[i / 2] = Convert.ToByte(hex.Substring(i, 2), 16);
    }
    return bytes;
}

然后把代码里的Convert.FromHexString替换成HexToByteArray即可。

验证逻辑

修改后再执行代码,应该就能成功解密出"123"了。原因很简单:

  • Azure CLI输出的加密相关字段是十六进制编码,必须用十六进制转字节数组
  • C# SDK内部加密返回的是Base64编码,所以自己加密解密时用Base64转换没问题
  • Azure CLI自己解密时会自动识别十六进制格式,所以它能正常解密

备注:内容来源于stack exchange,提问作者dotdev

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.15 09:53:08