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

使用RSA公钥加密时触发‘Bad Version of provider’错误的解决方法咨询

解决RSA公钥导入时的"Bad Version of provider"异常

咱们先把问题根源拎清楚:你手里的公钥是PEM格式(带-----BEGIN PUBLIC KEY-----和-----END PUBLIC KEY-----头尾标记),但你用的ImportCspBlob和ImportRSAPublicKey都不直接支持这种格式,这就是触发异常的核心原因。

具体问题拆解

  • ImportCspBlob要求输入的是Windows CSP专属的二进制Blob格式,和PEM完全不兼容,直接传入PEM字节肯定报错。
  • ImportRSAPublicKey需要的是DER编码的PKCS#1/PKCS#8公钥,但你给的是带Base64编码和注释头尾的PEM文本,自然无法解析。

解决方案

下面提供两种实用的解决方式,按需选择:

方式1:手动处理PEM格式(无需第三方库,.NET 5+友好)

先清理PEM的头尾标记,解码Base64内容,再导入公钥:

public static string EncryptFromPublicKey(string kwypath, string data) {
    try {
        // 读取并处理PEM公钥文本
        var pemContent = File.ReadAllText(kwypath);
        // 移除头尾标记和换行符,提取纯Base64内容
        var base64Key = pemContent
            .Replace("-----BEGIN PUBLIC KEY-----", "")
            .Replace("-----END PUBLIC KEY-----", "")
            .Replace("\r", "")
            .Replace("\n", "");
        // Base64解码为DER格式字节
        var publicKeyBytes = Convert.FromBase64String(base64Key);

        // 初始化RSA实例,导入公钥
        using var rsa = RSA.Create();
        // .NET 5+可直接用ImportFromPem,一步到位
        // rsa.ImportFromPem(pemContent);
        // 兼容旧版本用ImportSubjectPublicKeyInfo解析DER
        rsa.ImportSubjectPublicKeyInfo(publicKeyBytes, out _);

        // 执行加密:注意ASCII编码仅适用于纯ASCII文本,建议非ASCII场景用UTF8
        var dataToEncrypt = Encoding.ASCII.GetBytes(data);
        // PKCS1Padding对应参数RSAEncryptionPadding.Pkcs1
        var encryptedByteArray = rsa.Encrypt(dataToEncrypt, RSAEncryptionPadding.Pkcs1);

        // 转换为逗号分隔的字符串(和原逻辑保持一致)
        var sb = new StringBuilder();
        for (int i = 0; i < encryptedByteArray.Length; i++) {
            sb.Append(encryptedByteArray[i]);
            if (i < encryptedByteArray.Length - 1) sb.Append(",");
        }
        return sb.ToString();
    } catch (Exception e) {
        Console.WriteLine(e);
        throw;
    }
}

方式2:使用BouncyCastle库(兼容.NET Framework)

如果你的项目是.NET Framework,或需要更灵活的加密操作,可以借助BouncyCastle处理PEM:

  1. 先通过NuGet安装BouncyCastle包
  2. 修改代码如下:
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.OpenSsl;
using Org.BouncyCastle.Security;

public static string EncryptFromPublicKey(string kwypath, string data) {
    try {
        // 读取PEM公钥
        using var reader = File.OpenText(kwypath);
        var pemReader = new PemReader(reader);
        var publicKeyParam = (RsaKeyParameters)pemReader.ReadObject();
        // 转换为.NET兼容的RSA实例
        var rsa = (RSACryptoServiceProvider)DotNetUtilities.ToRSA(publicKeyParam);

        var dataToEncrypt = Encoding.ASCII.GetBytes(data);
        // false参数对应PKCS1Padding填充方式
        var encryptedByteArray = rsa.Encrypt(dataToEncrypt, false);

        var sb = new StringBuilder();
        for (int i = 0; i < encryptedByteArray.Length; i++) {
            sb.Append(encryptedByteArray[i]);
            if (i < encryptedByteArray.Length - 1) sb.Append(",");
        }
        return sb.ToString();
    } catch (Exception e) {
        Console.WriteLine(e);
        throw;
    }
}

额外提醒

  • 推荐用RSA.Create()替代旧的RSACryptoServiceProvider,它会自动适配系统加密提供者,减少版本兼容性问题。
  • 若文本包含非ASCII字符,Encoding.ASCII会导致数据丢失,建议替换为Encoding.UTF8。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.27 20:37:41