在.Net Core上使用非对称密钥

时间:2018-02-14 16:06:59

标签: cryptography .net-core rsa

我正在尝试运行此示例中的代码

https://docs.microsoft.com/en-us/dotnet/standard/security/how-to-store-asymmetric-keys-in-a-key-container

在.NetCore 2.0(Web应用程序)下。

但是当我尝试使用

执行任何一行时
CspParameters

我收到以下错误

'CspParameters' requires Windows Cryptographic API (CAPI), which is not available on this platform.

建议我如何解决这个问题。 感谢。

4 个答案:

答案 0 :(得分:6)

.NET不存储加密密钥,它最终是由它构建的加密平台提供的(或者不是)的功能。

要将CspParameters与.NET Core一起使用,您必须在Windows上运行;因为它是(旧)Windows Cryptographic API的一个非常薄的包装器。您无法在UAP中使用它,因为UAP仅允许使用较新的Cryptography:Next Generation(CNG)API。

macOS可以将密钥存储在Keychain中,但.NET Core不提供API来读取它们。

Linux(OpenSSL)除了&#34以外没有任何密钥存储机制;将其保存到文件并再次加载#34;,但.NET Core不支持从文件加载非对称密钥。

在跨平台机制中实现目标的唯一方法是让您的非对称密钥与X.509证书相关联。如果构建HasPrivateKey返回true的X509Certificate2对象,则可以将其保存到PFX / PKCS#12文件,然后从该文件加载;或者你可以将它添加到X509Store实例("我的"商店用于CurrentUser是最适合平台的那个),然后从X509Store实例读取它。

尽管您引用的页面声称是在2017年编写的,但它的真正含义是该内容已于该日期从msdn.microsoft.com上的先前位置移动。原始页面是在2008年编写的(至少,它是web.archive.org上的第一个版本),所以它早于.NET Core。

答案 1 :(得分:0)

因此,我们只想提供遇到此错误后发现的另一个选项。该CSP参数错误与RSACryptoServiceProvider有关。跨平台.NET Core存在一些问题。我们发现一个提到的Github issue改用RSA.Create()方法。我使用的是Bouncy Castle library,但仍使用RSACryptoServiceProvider。在撰写此答案时,看起来像这样。

        public static RSA ToRSA(RsaPrivateCrtKeyParameters privKey)
    {
        RSAParameters rp = ToRSAParameters(privKey);
        RSACryptoServiceProvider rsaCsp = new RSACryptoServiceProvider();
        rsaCsp.ImportParameters(rp);
        return rsaCsp;
    } 

所以我们在类中将其替换为私有方法,

            private RSA ToRSA(RsaPrivateCrtKeyParameters parameters)
        {
            RSAParameters rp = DotNetUtilities.ToRSAParameters(parameters);
            return RSA.Create(rp);
        }

此命令在linux中运行,没有错误。弹性可能只需要更新其库即可。

答案 2 :(得分:0)

使用此方法从“密钥”字符串导入公共密钥,确保安装BouncyCastle.NetCore nuget软件包

  public static RSACryptoServiceProvider ImportPublicKey(string pem)
    {
        PemReader pr = new PemReader(new StringReader(pem));
        AsymmetricKeyParameter publicKey = (AsymmetricKeyParameter)pr.ReadObject();
        RSAParameters rsaParams = DotNetUtilities.ToRSAParameters((RsaKeyParameters)publicKey);

        RSACryptoServiceProvider csp = new RSACryptoServiceProvider();// cspParams);
        csp.ImportParameters(rsaParams);
        return csp;
    }

然后您可以如下所示加密数据

 public static string Encryption(string data,string publickey)
    {
        var testData = Encoding.GetEncoding("iso-8859-1").GetBytes(strText);

        using (var rsa = ImportPublicKey(publickey))
        {
            try
            {
                var encryptedData = rsa.Encrypt(testData, false);
                var base64Encrypted = Convert.ToBase64String(encryptedData);
                return base64Encrypted;
            }
            finally
            {
                rsa.PersistKeyInCsp = false;
            }
        }
    }

答案 3 :(得分:0)

现在,您可以跨平台运行它,并且只要您在.netcore 3.0或更高版本上,并且可以添加最新的 System.Security.Cryptography.Cng nuget包(请注意!仅在您的项目没有多目标的情况下才能工作-它只能以 netcoreapp3.0 )为目标:

using (ECDsa key = ECDsa.Create())
            {
                key.ImportPkcs8PrivateKey(Convert.FromBase64String(privateKey), out _);

                return Jose.JWT.Encode
                    (
                    payload: payload,
                    key: key,
                    algorithm: JwsAlgorithm.ES256,
                    extraHeaders: extraHeader
                    );
            }