【发布时间】:2020-12-04 14:31:47
【问题描述】:
我有一项服务需要对连接文本进行加密和解密。我不想硬编码密码,所以我决定使用证书,但我希望能够在第一次打开设置 UI(单独的配置应用程序)时将其添加到商店。
我有代码检查现有证书,如果找不到证书,则添加一个新证书。
private static void GenerateNewSecurityCertificate()
{
var ecdsa = ECDsa.Create(); // generate asymmetric key pair
var request = new CertificateRequest($"cn={CertificateName}", ecdsa, HashAlgorithmName.SHA512);
var cert = request.CreateSelfSigned(DateTimeOffset.Now, DateTimeOffset.Now.AddYears(50));
File.WriteAllBytes("c:\\temp\\EncryptionCert.pfx", cert.Export(X509ContentType.Pfx, _certificatePassword));
}
private static void AddCertificateToStore()
{
using (var store = new X509Store(StoreName.TrustedPublisher, StoreLocation.LocalMachine))
{
store.Open(OpenFlags.ReadWrite);
using (var cert = new X509Certificate2("c:\\temp\\EncryptionCert.pfx", _certificatePassword,
X509KeyStorageFlags.PersistKeySet | X509KeyStorageFlags.MachineKeySet))
{
store.Add(cert);
}
}
}
我在尝试检索公钥时遇到了问题
using (var store = new X509Store(StoreName.TrustedPublisher, StoreLocation.LocalMachine))
{
store.Open(OpenFlags.ReadOnly);
using (var cert = store.Certificates.Find(X509FindType.FindBySubjectName, CertificateName, false)[0])
{
var publicKey = cert.GetRSAPublicKey();
encryptedKey = publicKey.Encrypt(aesKey.Key, RSAEncryptionPadding.OaepSHA512);
}
}
当我调用cert.GetRSAPublicKey() 时,我得到一个空值返回。有谁知道我可能做错了什么?
更新:
我更新了GenerateNewSecurityCertificate 阅读
var rsa = RSA.Create();
var request = new CertificateRequest($"cn={CertificateName}", rsa, HashAlgorithmName.SHA512, RSASignaturePadding.Pkcs1);
我现在可以获取公钥,但读取异常
"The parameter is incorrect"
at System.Security.Cryptography.NCryptNative.EncryptData[T](SafeNCryptKeyHandle key, Byte[] data, T& paddingInfo, AsymmetricPaddingMode paddingMode, NCryptEncryptor`1 encryptor)
我打电话给publicKey.Encrypt。
【问题讨论】:
-
您在
GenerateNewSecurityCertificate中创建了一个ECDSA 密钥对,但最后导出了一个(公共)RSA 密钥。使用 RSA 或 EC。对于 EC 密钥,还有其他检索方法,例如GetPublicKey/GetPublicKeyString以二进制/十六进制编码格式返回(未压缩的)原始 EC 公钥。使用GetRSAPublicKey检索公共 RSA 密钥。 -
@Topaco - 感谢您的回复。我更新了 GenerateNewSecurityCertificate 以读取 var rsa = RSA.Create(); var request = new CertificateRequest($"cn={CertificateName}", rsa, HashAlgorithmName.SHA512, RSASignaturePadding.Pkcs1);我现在可以获取公钥,但在调用 publicKey.Encrypt 时会出现“参数不正确”的异常。在 System.Security.Cryptography.NCryptNative.EncryptData[T](SafeNCryptKeyHandle key, Byte[] data, T& paddingInfo, AsymmetricPaddingMode paddingMode, NCryptEncryptor`1 加密器)
-
这可能是由于选择了关键参数,请看我的回答。
-
您需要增加 RSA 密钥大小(@Topaco 的回答)或减少 OAEP 填充大小(例如,使用 OAEP-SHA256)。您可能正在尝试存储 32 个字节,将其与 crypto.stackexchange.com/a/42100/36951 的图表进行比较。
-
@bartonjs - 我在回答中提到了较小摘要的替代方案。但是由于 OP 使用 1024 位密钥(并且只有使用此密钥大小,问题才会在加密 AES 密钥的上下文中实际发生),在我看来这是错误的方式here,因为现在 1024 位密钥太小了。
标签: c# encryption x509 encryption-symmetric