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的公钥