Cryptography 在.Net内核上使用非对称密钥

Cryptography 在.Net内核上使用非对称密钥,cryptography,.net-core,rsa,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

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

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.
请就我如何解决这一问题提出建议。
谢谢。

.NET不存储加密密钥,这最终是它所构建的加密平台提供的一项功能

要在.NET Core中使用CSP参数,您必须在Windows上运行;因为这是(旧的)Windows加密API上非常薄的包装。您不能在UAP中使用它,因为UAP只允许更新的加密技术:下一代(CNG)API

macOS可以将密钥存储在密钥链中,但.NETCore不提供读取密钥的API

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

在跨平台机制中实现目标的唯一方法是将非对称密钥与X.509证书相关联。如果生成的X509Certificate2对象的
HasPrivateKey
返回true,则可以将其保存到PFX/PKCS#12文件中,然后从该文件加载;或者,您可以将其添加到X509Store实例(CurrentUser的“我的”存储是跨平台工作得最好的存储),然后从X509Store实例中读取它


尽管您引用的页面声称是在2017年编写的,但它真正的意思是内容是在该日期从msdn.microsoft.com上的先前位置移动的。最初的页面是在2008年编写的(至少,这是web.archive.org上的第一个热门页面),因此它早在.NET Core之前就存在了。

因此,我们只想提供我们遇到此错误时发现的另一个选项。该CSP参数错误与。这在跨平台.NET核心方面存在一些问题。我们发现了一个Github,它提到使用RSA.Create()方法代替。我使用的是一个弹跳城堡,它仍然使用RSACryptServiceProvider。在写这个答案的时候,看起来是这样的

        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);
        }
所以我们在类中用一个私有方法替换了它,看起来像这样

        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中运行,没有错误。Bouncy可能只需要更新他们的LIB

使用此方法从密钥字符串导入公钥。请确保安装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;
            }
        }
    }

现在,您可以跨平台执行此操作,只要您在.netcore 3.0或更高版本上,并且添加最新的System.Security.Cryptography.Cngnuget软件包(注意!只有在您的项目不是多目标的情况下,此操作才有效-它只能针对netcoreapp3.0):

使用(ECDsa key=ECDsa.Create())
{
key.ImportPkcs8PrivateKey(从Base64字符串(privateKey)转换为;
返回Jose.JWT.Encode
(
有效载荷:有效载荷,
钥匙:钥匙,
算法:JwsAlgorithm.ES256,
extraHeader:extraHeader
);

}
我尝试过此解决方案,但在此行产生异常:var encryptedData=rsa.Encrypt(testData,false);Internal.Cryptography.CryptothWherPer.WindowsCryptographyException:“错误长度”增加密钥长度大小可能使用密钥大小超过4096的公钥