使用Azure Key Vault RSA-HSM私钥解密JWE时遇认证标签不匹配问题求助
问题描述
尝试解密用代码签名证书公钥加密的JWE令牌,JWE头信息如下:
{ "alg": "RSA-OAEP", "enc": "A256GCM" }
代码签名证书的私钥为RSA-HSM类型,存储在Azure Key Vault HSM中无法导出。当前操作流程是用密钥库API解密JWE的EncryptedKey组件,再用解密后的密钥初始化System.Security.Cryptography.AesGcm,但解密时提示错误:"The computed authentication tag did not match the input authentication tag."
现有代码
public async Task<string> decryptJweAsync(string response) { var jweToken = JweToken.FromString(response); var keyClient = new KeyClient(new Uri(_azureKeyVault.Value.KeyVaultBaseUri), new DefaultAzureCredential()); var rsaHsmKey = await keyClient.GetKeyAsync(_myConfiguration.Value.PrivateKey); var cryptoClient = new CryptographyClient(rsaHsmKey.Value.Id, new DefaultAzureCredential()); byte[] plaintextBytes = new byte[jweToken.Ciphertext.Length]; var cekBytes = await cryptoClient.DecryptAsync(EncryptionAlgorithm.RsaOaep, jweToken.Recipients[0].EncryptedCek); System.Security.Cryptography.AesGcm aesGcm = new System.Security.Cryptography.AesGcm(cekBytes.Plaintext); aesGcm.Decrypt(jweToken.Iv, jweToken.Ciphertext, jweToken.AuthTag, plaintextBytes); var decrypted = Encoding.UTF8.GetString(plaintextBytes); //other codes for verification below }
解决建议
必须传入JWE保护头作为附加认证数据(AAD)
A256GCM解密要求将JWE的已编码保护头作为附加认证数据传入,这是当前代码缺失的核心问题。修改Decrypt调用:// 获取UTF-8编码的JWE保护头字节 byte[] aadBytes = Encoding.UTF8.GetBytes(jweToken.ProtectedHeader); // 传入AAD参数完成解密 aesGcm.Decrypt(jweToken.Iv, jweToken.Ciphertext, jweToken.AuthTag, plaintextBytes, aadBytes);确认CEK解密算法与JWE头匹配
JWE头的alg为RSA-OAEP,默认对应Azure Key Vault的SHA-1哈希实现,但部分加密方可能使用SHA-256(对应RSA-OAEP-256)。如果加密方用的是SHA-256,需修改解密算法:var cekBytes = await cryptoClient.DecryptAsync(EncryptionAlgorithm.RsaOaep256, jweToken.Recipients[0].EncryptedCek);验证JWE组件的字节解析正确性
确认jweToken.Iv、jweToken.Ciphertext、jweToken.AuthTag均为Base64URL解码后的原始字节数组,而非编码后的字符串。部分JWE库可能自动处理解码,但需确认JweToken类的属性返回值类型。检查Azure Key Vault密钥权限与类型
确保密钥为RSA-HSM类型,且当前凭据已被授予Decrypt权限。权限不足或密钥类型不匹配可能导致CEK解密不完整,进而引发认证标签校验失败。
内容的提问来源于stack exchange,提问作者user23501363

