【问题标题】:RSACryptoServiceProvider rsa = (RSACryptoServiceProvider)cert.PublicKey.Key does not work in .NET CoreRSACryptoServiceProvider rsa = (RSACryptoServiceProvider)cert.PublicKey.Key 在 .NET Core 中不起作用
【发布时间】:2020-02-10 22:00:39
【问题描述】:

我有一个用 .NET Framework 2.0 编译的程序集(是的,很老的东西),它使用证书的公钥执行加密。代码极其简单:

X509Certificate2 objCert = new X509Certificate2(path);
RSACryptoServiceProvider rsa = (RSACryptoServiceProvider)objCert.PublicKey.Key;
byte [] EncrRes = rsa.Encrypt(data, false);

这将继续适用于所有最新版本的 .NET Framework,但拒绝在 .NET Core 下运行。我收到了两条不同但相似的错误消息。

Windows 10: 无法将“System.Security.Cryptography.RSACng”类型的对象转换为“System.Security.Cryptography.RSACryptoServiceProvider”类型。

Linux: 无法将“System.Security.Cryptography.RSAOpenSsl”类型的对象转换为“System.Security.Cryptography.RSACryptoServiceProvider”类型。

有没有办法对这个简单的操作进行编码,以便它可以在 .NET Framework 2.0+ 和 .NET core 上运行?

提前致谢。

【问题讨论】:

    标签: .net .net-core x509certificate2


    【解决方案1】:

    在 .NET Core 中,X509Certificate2.PublicKey.KeyX509Certificate2.PrivateKey 使用特定于平台的密钥实现。在 Windows 上,有两种实现方式,旧版 RSACryptoServiceProvider 和现代 RSACng

    您必须更改访问这些属性的方式。并且不要访问它们。相反,使用扩展方法:X509Certificate2 Extension Methods。它们返回您将使用的安全抽象类。不要尝试对任何东西使用显式强制转换。对于RSA 键使用RSA 类等等。

    X509Certificate2 objCert = new X509Certificate2(path);
    // well, it is reasonable to check the algorithm of public key. If it is ECC,
    // then call objCert.GetECDsaPublicKey()
    RSA rsa = objCert.GetRsaPublicKey();
    byte [] EncrRes = rsa.Encrypt(data, RSAEncryptionPadding.Pkcs1);
    

    【讨论】:

    • 感谢您的回复,但 GetRsaPublicKey 在 .NET 2.0 中不可用。我已经在下面找到并发布了一个解决方案。
    【解决方案2】:

    我自己想出来的。而不是

    RSACryptoServiceProvider rsa = (RSACryptoServiceProvider)objCert.PublicKey.Key;
    

    RSA rsa_helper = (RSA)objCert.PublicKey.Key;
    RSAParameters certparams = rsa_helper.ExportParameters(false);
    RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
    RSAParameters paramcopy = new RSAParameters();
    paramcopy.Exponent = certparams.Exponent;
    paramcopy.Modulus = certparams.Modulus;
    rsa.ImportParameters(paramcopy);
    

    适用于 .NET 2.0+ 和 .NET Core!

    【讨论】:

    • 为什么你需要那个旧的RSACryptoServiceProvider?真的不鼓励使用它。在我的其他回复中找到正确的方法。
    • 为了向后兼容。
    • .NET Core 不向后兼容 .NET 2.0。
    • 如果编码正确,为 .NET 2.0 编写的组件可以与 .NET Core 一起使用。
    • 使用这种方法,您只能坚持使用 Windows,而不会从 .NET Core 跨平台中获得任何好处。您的代码不会在 Linux 或 Mac 上运行,因为没有这样的 RSACryptoServiceProvider 类。
    猜你喜欢
    • 1970-01-01
    • 2014-12-11
    • 1970-01-01
    • 2020-12-26
    • 2021-10-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-09-20
    相关资源
    最近更新 更多