【发布时间】:2019-07-29 09:19:09
【问题描述】:
我目前正在尝试构建一个系统来加密客户数据并将其添加到另一台服务器上的远程 MSMQ 队列中。然后,每 X 分钟运行一次的作业会获取数据,该作业将尝试解密数据并对其进行处理。
要求我们必须使用 .PFX 证书进行加密/解密(我知道这不是最有效的做事方式,但有要求,我无法更改此设置)。
我目前正在使用使用 Open-SSL 的自签名证书:
openssl req -newkey rsa:2048 -nodes -keyout key.pem -x509 -days 365 -out certificate.pem
openssl pkcs12 -inkey key.pem -in certificate.pem -export -out certificate.p12
我已成功加密数据,但每次尝试解密时,都会出现一般的“参数不正确”异常。
为了加载证书,我们将 .PFX 文件保存在机器本地,并使用 X509Certificate2 类导入它并使用它来加密和解密。这是我正在使用的辅助类的简化版:
public static string EncryptData(string data)
{
var certificate = GetCertificate();
using (var rsa = certificate.PublicKey.Key as RSACryptoServiceProvider)
{
var dataBytes = Convert.FromBase64String(data);
var encryptedBytes = rsa.Encrypt(dataBytes, false);
return Convert.ToBase64String(encryptedBytes);
}
}
public static string DecryptData(string data)
{
var certificate = GetCertificate();
using (var rsa = certificate.PrivateKey as RSACryptoServiceProvider)
{
var dataBytes = Convert.FromBase64String(data);
var decryptedBytes = rsa.Decrypt(dataBytes, false);
return Convert.ToBase64String(decryptedBytes);
}
}
private static X509Certificate2 GetCertificate()
{
var certificate = new X509Certificate2();
certificate.Import("certificatePath", "certificatePassword", X509KeyStorageFlags.PersistKeySet);
return certificate;
}
错误总是发生在“rsa.Decrypt()”调用上。
我尝试了以下方法:
加密后立即在我的“EncryptData”方法中调用“rsa.Decrypt()”。这没有问题,并且“rsa.Decrypt”给了我与原始数据字节相同的字节。
在“EncryptData”调用之后直接调用“DecryptData”方法。发生同样的问题,我得到“参数不正确”的异常
这就是为什么我怀疑创建了一个“新”X509Certificate2 的事实,即私钥不再相同并且不能再解密数据。
请注意,我不是安全专家,也没有使用过 X509 证书或任何加密技术,所以我有点超出我的深度,可能正在做一些非常愚蠢的事情,所以如果我是,请告诉我。
更新 1 (08/03/2019)
已根据@bartonjs 给出的建议点 1-3 和 5 更新了代码代码
public static string EncryptData(string data)
{
var certificate = GetCertificate();
using (var rsa = certificate.GetRSAPublicKey())
{
var dataBytes = Convert.FromBase64String(data);
var encryptedBytes = rsa.Encrypt(dataBytes, RSAEncryptionPadding.OaepSHA1);
return Convert.ToBase64String(encryptedBytes);
}
}
public static string DecryptData(string data)
{
var certificate = GetCertificate();
using (var rsa = certificate.GetRSAPrivateKey())
{
var dataBytes = Convert.FromBase64String(data);
var decryptedBytes = rsa.Decrypt(dataBytes, RSAEncryptionPadding.OaepSHA1);
return Convert.ToBase64String(decryptedBytes);
}
}
private static X509Certificate2 GetCertificate()
{
var certificate = new X509Certificate2("certificatePath", "certificatePassword", X509KeyStorageFlags.PersistKeySet);
return certificate;
}
添加错误信息:
Message: The parameter is incorrect.
Stack Trace:
at System.Security.Cryptography.NCryptNative.DecryptData[T](SafeNCryptKeyHandle key, Byte[] data, T& paddingInfo, AsymmetricPaddingMode paddingMode, NCryptDecryptor`1 decryptor)
at System.Security.Cryptography.NCryptNative.DecryptDataOaep(SafeNCryptKeyHandle key, Byte[] data, String hashAlgorithm)
at System.Security.Cryptography.RSACng.Decrypt(Byte[] data, RSAEncryptionPadding padding)
【问题讨论】:
标签: c# encryption x509certificate2 pfx