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

Visual Studio中C# RSA解密报错:Key not valid for use in specified state

RSA解密报错:System.Security.Cryptography.CryptographicException: 'Key not valid for use in specified state'

问题场景

在Visual Studio开发大学C#项目时,自定义RsaEncryptionService类实现RSA加密解密逻辑,测试解密随机字符串正常,但读取Key.txt文件内容解密时触发上述错误。

自定义RsaEncryptionService类代码

public class RsaEncryptionService
{
    private static RSACryptoServiceProvider csp = new RSACryptoServiceProvider(2048);
    private RSAParameters _privateKey;
    private RSAParameters _publicKey;

    public RsaEncryptionService()
    {
        _privateKey = csp.ExportParameters(true);
        _publicKey = csp.ExportParameters(false);
    }

    public string GetPublicKey()
    {
        var sw = new StringWriter();
        var xmlSerializer = new XmlSerializer(typeof(RSAParameters));
        xmlSerializer.Serialize(sw, _publicKey);
        return sw.ToString();
    }

    public string GetPrivateKey()
    {
        var sw = new StringWriter();
        var xmlSerializer = new XmlSerializer(typeof(RSAParameters));
        xmlSerializer.Serialize(sw, _privateKey);
        return sw.ToString();
    }

    public string Encript(string plainText)
    {
        csp = new RSACryptoServiceProvider();
        csp.ImportParameters(_publicKey);
        var dataBytes = Encoding.Unicode.GetBytes(plainText);
        var cypherData = csp.Encrypt(dataBytes, false);
        return Convert.ToBase64String(cypherData);
    }

    public string Decript(string cypherText)
    {
        var dataBytes = Convert.FromBase64String(cypherText);
        csp.ImportParameters(_privateKey);
        var plaintextBytes = csp.Decrypt(dataBytes, false);
        return Encoding.Unicode.GetString(plaintextBytes);
    }
}

触发错误的测试代码

var rsa = new RsaEncryptionService();
byte[] text = File.ReadAllBytes(Application.StartupPath + "\\Export\\Export.txt");
string key = File.ReadAllText(Application.StartupPath + "\\Export\\Key.txt");
string iv = File.ReadAllText(Application.StartupPath + "\\Export\\IV.txt");

var DecryptedKey = rsa.Decript(key);

问题分析

  1. 静态CSP实例的状态污染:类中使用静态RSACryptoServiceProvider字段,在Encript方法中重新实例化覆盖了静态对象,后续Decript方法使用这个被修改后的实例导入私钥,导致密钥状态不匹配。
  2. 多实例共享冲突:静态字段会被所有RsaEncryptionService实例共享,若多次实例化类,会引发密钥状态混乱。
  3. 潜在的密钥不匹配:若Key.txt中的内容不是当前实例公钥加密生成的Base64字符串,也会触发解密失败。

修复方案

修改后的RsaEncryptionService类

public class RsaEncryptionService
{
    private readonly RSAParameters _privateKey;
    private readonly RSAParameters _publicKey;

    public RsaEncryptionService()
    {
        using var csp = new RSACryptoServiceProvider(2048);
        _privateKey = csp.ExportParameters(true);
        _publicKey = csp.ExportParameters(false);
    }

    public string GetPublicKey()
    {
        var sw = new StringWriter();
        var xmlSerializer = new XmlSerializer(typeof(RSAParameters));
        xmlSerializer.Serialize(sw, _publicKey);
        return sw.ToString();
    }

    public string GetPrivateKey()
    {
        var sw = new StringWriter();
        var xmlSerializer = new XmlSerializer(typeof(RSAParameters));
        xmlSerializer.Serialize(sw, _privateKey);
        return sw.ToString();
    }

    public string Encrypt(string plainText)
    {
        using var csp = new RSACryptoServiceProvider();
        csp.ImportParameters(_publicKey);
        var dataBytes = Encoding.Unicode.GetBytes(plainText);
        var cypherData = csp.Encrypt(dataBytes, false);
        return Convert.ToBase64String(cypherData);
    }

    public string Decrypt(string cypherText)
    {
        var dataBytes = Convert.FromBase64String(cypherText);
        using var csp = new RSACryptoServiceProvider();
        csp.ImportParameters(_privateKey);
        var plaintextBytes = csp.Decrypt(dataBytes, false);
        return Encoding.Unicode.GetString(plaintextBytes);
    }
}

关键修改说明

  • 移除静态RSACryptoServiceProvider字段,改为在构造函数、加密/解密方法中使用局部实例,通过using确保资源自动释放。
  • 修正方法名拼写错误:Encript→Encrypt、Decript→Decrypt,符合C#命名规范。
  • 每个加密/解密操作使用独立的RSACryptoServiceProvider实例,彻底避免状态污染问题。

额外检查项

  1. 确认Key.txt中的内容是当前RsaEncryptionService实例公钥加密生成的Base64字符串,若为外部密钥加密的内容,需对应导入正确的私钥。
  2. 读取文件时确保无多余空格、换行符,可通过key = key.Trim()清理内容后再解密。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 02:06:02