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

C#使用PKCS8私钥解密JWE遇RSACng已释放对象异常

解决C#中使用PKCS8私钥解密JWE时的"Cannot access a disposed object"异常

核心问题原因

代码抛出Cannot access a disposed object. Object name: 'RSACng'异常,根源在LoadPrivateKeyFromPem方法:

static RSA LoadPrivateKeyFromPem(string privateKeyPem)
{
    using var key = RSA.Create(); // using会在方法结束时自动释放对象
    key.ImportFromPem(privateKeyPem);
    return key; // 返回时对象已被释放,后续使用必然报错
}

using关键字会在代码块结束后自动调用RSA对象的Dispose方法,导致返回的对象处于已释放状态,后续用它创建RsaSecurityKey并解密时就会触发异常。

修正后的完整代码

以下是修复后的代码,同时调整了Token验证参数(仅保留解密所需配置,关闭不必要的验证项):

using System;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Cryptography;
using Microsoft.IdentityModel.Tokens;

namespace Transaction
{
    public static class CallDecryptJwe
    {
        public static void DecryptJwe(string jweString, string decryptionKeyInput)
        {
            string jweToken = jweString;
            string privateKeyPem = decryptionKeyInput;

            JwtSecurityTokenHandler handler = new JwtSecurityTokenHandler();

            try
            {
                // 加载私钥,用using包裹确保使用完后释放资源
                using RSA rsaPrivateKey = LoadPrivateKeyFromPem(privateKeyPem);
                
                var rsaSecurityKey = new RsaSecurityKey(rsaPrivateKey);
                var validationParameters = new TokenValidationParameters
                {
                    TokenDecryptionKey = rsaSecurityKey,
                    // 仅需解密JWE,关闭其他验证项
                    ValidateIssuer = false,
                    ValidateAudience = false,
                    ValidateLifetime = false
                };

                // 解密并处理JWE
                var claimsPrincipal = handler.ValidateToken(jweToken, validationParameters, out var securityToken);

                Console.WriteLine("解密后的Claims:");
                foreach (var claim in claimsPrincipal.Claims)
                {
                    Console.WriteLine($"{claim.Type}: {claim.Value}");
                }

                // 直接获取明文JSON(可选)
                if (securityToken is JwtSecurityToken jwtToken)
                {
                    Console.WriteLine("\n明文JSON内容:");
                    Console.WriteLine(jwtToken.Payload.SerializeToJson());
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine($"错误信息: {ex.Message}");
                Console.WriteLine($"异常详情: {ex.ToString()}");
            }
        }

        static RSA LoadPrivateKeyFromPem(string privateKeyPem)
        {
            // 移除using,由调用方负责释放RSA对象
            RSA key = RSA.Create();
            key.ImportFromPem(privateKeyPem);
            return key;
        }
    }
}

额外验证点

  1. 密钥格式确认:你的PKCS8私钥格式正确,ImportFromPem可直接加载,无需额外转换。
  2. 算法匹配:JWE头部指定的RSA-OAEP-256算法,RsaSecurityKey默认支持,无需额外配置。
  3. 资源管理:调用LoadPrivateKeyFromPem时用using包裹RSA对象,确保解密完成后正确释放加密资源,避免内存泄漏。

内容的提问来源于stack exchange,提问作者Adam Williams

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 08:27:00