我正在尝试运行此示例中的代码
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.
建议我如何解决这个问题。 感谢。
答案 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
);
}