在.NET Full Framework(4.6.2)和.net core 2中使用RSA时遇到问题。现有的完整框架应用程序使用证书加密和解密文件。这个程序是野外的,无法更改。目标是创建一个兼容的.net核心应用程序,可以与现有应用程序交换加密文件。简而言之,对称AES密钥用于加密实际文件数据。然后使用接收器公钥加密AES密钥。
我在3/4的路上工作了。 那就是:
在最后一种情况下,我收到WindowsCryptographicException
消息The parameter is incorrect
。
我没有得到更好的错误消息,尤其是哪个参数看起来不正确。
问题:我做错了什么? ;)或者我怎样才能确切地知道哪些参数错误地知道我需要改变什么才能使它工作。
其他信息和代码:
完整的4.6.2框架应用程序使用接收者的证书:
var rsa = receiverCertificate.PublicKey.Key as RSACryptoServiceProvider;
// *snip* create AES key
var encryptedAesKey = rsa.Encrypt(aesManaged.Key, false);
解密时,会执行以下操作:
var rsa = receiverCertificate.PrivateKey as RSACryptoServiceProvider;
// *snip* extract encrypted aes key from encrypted file
var decryptedKey = rsa.Decrypt(encryptedKey, false);
现在,在 .net核心中,无法将密钥转换为RSACryptoServiceProvider
。
为了重用大部分现有代码和端口到.NET核心,我编写了这两个扩展方法来从密钥中获取RSACryptoServiceProvider,如下所示:
public static RSACryptoServiceProvider GetPublicKeyRsaCryptoServiceProvider(this X509Certificate2 certificate)
{
// Get params from public key
var rsa = certificate.GetRSAPublicKey();
var rsaParameters = rsa.ExportParameters(false);
var csp = new RSACryptoServiceProvider(rsa.KeySize, new CspParameters()
{
ProviderType = 24,
ProviderName = "Microsoft Enhanced RSA and AES Cryptographic Provider",
});
csp.ImportParameters(rsaParameters);
return rsacsp;
}
public static RSACryptoServiceProvider GetPrivateKeyRsaCryptoServiceProvider(this X509Certificate2 certificate)
{
// Get params from private key
var rsa = certificate.GetRSAPrivateKey();
var rsaParameters = rsa.ExportParameters(true);
var csp = new RSACryptoServiceProvider(rsa.KeySize, new CspParameters()
{
ProviderType = 24,
ProviderName = "Microsoft Enhanced RSA and AES Cryptographic Provider",
});
csp.ImportParameters(rsaParameters);
return rsacsp;
}
我将现有代码移植到.net核心时更改的唯一行是将公钥/私钥转换为RSACryptoServiceProvider
的行,并使用对我的扩展方法的调用替换了转换。
在更改更多内容并从RsaCryptoServiceProvider完全转移到RSA类之前,以便.net核心应用程序最终可以在其他操作系统上运行,我希望这在完全往返中首先运行。
有关其他信息:我抓住了X509Certificate2
这样的实例:
using (var myStore = new X509Store(StoreName.My, StoreLocation.CurrentUser))
{
myStore.Open(OpenFlags.ReadOnly);
var certs = myStore.Certificates.Find(X509FindType.FindByKeyUsage, X509KeyUsageFlags.DataEncipherment.ToString(), true);
return certs.FirstOrDefault(c => c.Subject.Contains("receiver"));
}