Encrypt/Decrypt 使用自己生成的证书 C# 失败(缺少私钥)
Encrypt/Decrypt failed(private key missing) with ownly generated certificate C#
我需要借助 C# 代码生成 RSA 证书(自签名证书)。我使用下面的代码创建了证书。
public bool CreateRSACertificate()
{
RSA rsaKey = RSA.Create();
CertificateRequest certRequest = new CertificateRequest("cn=MyApplication", rsaKey, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1);
certRequest.CertificateExtensions.Add(new X509BasicConstraintsExtension(true, false, 0, true));
certRequest.CertificateExtensions.Add(new X509SubjectKeyIdentifierExtension(certRequest.PublicKey, false));
X509Certificate2 certificate = certRequest.CreateSelfSigned(DateTimeOffset.Now, DateTimeOffset.Now.AddYears(5));
byte[] certData = certificate.Export(X509ContentType.Pfx, "TestPassword");
X509Certificate2 cert = new X509Certificate2(certData, "TestPassword", X509KeyStorageFlags.Exportable);
File.WriteAllBytes("MyCertificate.pfx", cert.Export(X509ContentType.Pfx, "TestPassword"));
return true;
}
然后,我尝试使用我使用以下代码创建的证书文件来加密数据。
public bool EncryptAndDecryptFile()
{
string data = "{data: 'mydate123@gmail.com'}";
X509Certificate2 certificate = new X509Certificate2("MyCertificate.pfx", "TestPassword", X509KeyStorageFlags.Exportable);
if (certificate.HasPrivateKey) {
Console.WriteLine("Private key available "); // It's says like the private key was available
}
RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
rsa.FromXmlString(certificate.PublicKey.Key.ToXmlString(false));
byte[] bytes = Encoding.ASCII.GetBytes(data);
var encryptedData = rsa.Encrypt(bytes, false); //It seems the data encrypted. I'm not sure.But, I can able to see some encrypted data.
using (certificate.GetRSAPrivateKey()) {
RSACryptoServiceProvider drsa = new RSACryptoServiceProvider();
drsa.FromXmlString(certificate.PrivateKey.ToXmlString(false));
var decdata = drsa.Decrypt(encryptedData, false); // Here, I see some exception.
someString = Encoding.ASCII.GetString(decdata);
}
Console.WriteLine("someString someString ::: " + someString);
return true;
}
虽然,运行上面的代码我看到了下面的错误。
Unhandled exception. Internal.Cryptography.CryptoThrowHelper+WindowsCryptographicException: Key not valid for use in specified state.
at Internal.NativeCrypto.CapiHelper.ExportKeyBlob(Boolean includePrivateParameters, SafeKeyHandle safeKeyHandle)
at System.Security.Cryptography.RSACryptoServiceProvider.ExportParameters(Boolean includePrivateParameters)
at ConfigUtility.X509Certificate.ReadRSACertificate()
要验证证书,我有以下命令,
certutil -dump MyCertificate.pfx
所以,上面的实用程序给了我下面的输出,
================ Certificate 0 ================
================ Begin Nesting Level 1 ================
Element 0:
Serial Number: 054834637a713ecf
Issuer: CN=MyApplication
NotBefore: 29-05-2020 13:49
NotAfter: 29-05-2025 13:49
Subject: CN=MyApplication
Signature matches Public Key
Root Certificate: Subject matches Issuer
Cert Hash(sha1): 16e83e8a92a38b948adad03a86768e27115851d4
---------------- End Nesting Level 1 ----------------
Provider = Microsoft Software Key Storage Provider
Private key is NOT plain text exportable
Encryption test passed
CertUtil: -dump command completed successfully.
事实上,你在这一行得到了例外:
drsa.FromXmlString(certificate.PrivateKey.ToXmlString(false));
整个加密和解密代码段都不正确,你在乱用旧的已弃用的 RSACryptoServiceProvider
并进行不必要的操作。该方法应如下所示:
public bool EncryptAndDecryptFile() {
string data = "{data: 'mydate123@gmail.com'}";
X509Certificate2 certificate = new X509Certificate2("MyCertificate.pfx", "TestPassword", X509KeyStorageFlags.Exportable);
if (certificate.HasPrivateKey) {
Console.WriteLine("Private key available "); // It's says like the private key was available
}
Byte[] encryptedData = new Byte[0];
using (RSA pubKey = certificate.GetRSAPublicKey()) {
byte[] bytes = Encoding.ASCII.GetBytes(data);
encryptedData = rsa.Encrypt(bytes, RSAEncryptionPadding.OaepSHA256);
}
// assuming, encryptedData is not null
String someString = String.Empty;
using (RSA prKey = certificate.GetRSAPrivateKey()) {
Byte[] decdata = prKey.Decrypt(encryptedData, RSAEncryptionPadding.OaepSHA256);
someString = Encoding.ASCII.GetString(decdata);
}
return data.Equals(someString);
}
我需要借助 C# 代码生成 RSA 证书(自签名证书)。我使用下面的代码创建了证书。
public bool CreateRSACertificate()
{
RSA rsaKey = RSA.Create();
CertificateRequest certRequest = new CertificateRequest("cn=MyApplication", rsaKey, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1);
certRequest.CertificateExtensions.Add(new X509BasicConstraintsExtension(true, false, 0, true));
certRequest.CertificateExtensions.Add(new X509SubjectKeyIdentifierExtension(certRequest.PublicKey, false));
X509Certificate2 certificate = certRequest.CreateSelfSigned(DateTimeOffset.Now, DateTimeOffset.Now.AddYears(5));
byte[] certData = certificate.Export(X509ContentType.Pfx, "TestPassword");
X509Certificate2 cert = new X509Certificate2(certData, "TestPassword", X509KeyStorageFlags.Exportable);
File.WriteAllBytes("MyCertificate.pfx", cert.Export(X509ContentType.Pfx, "TestPassword"));
return true;
}
然后,我尝试使用我使用以下代码创建的证书文件来加密数据。
public bool EncryptAndDecryptFile()
{
string data = "{data: 'mydate123@gmail.com'}";
X509Certificate2 certificate = new X509Certificate2("MyCertificate.pfx", "TestPassword", X509KeyStorageFlags.Exportable);
if (certificate.HasPrivateKey) {
Console.WriteLine("Private key available "); // It's says like the private key was available
}
RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
rsa.FromXmlString(certificate.PublicKey.Key.ToXmlString(false));
byte[] bytes = Encoding.ASCII.GetBytes(data);
var encryptedData = rsa.Encrypt(bytes, false); //It seems the data encrypted. I'm not sure.But, I can able to see some encrypted data.
using (certificate.GetRSAPrivateKey()) {
RSACryptoServiceProvider drsa = new RSACryptoServiceProvider();
drsa.FromXmlString(certificate.PrivateKey.ToXmlString(false));
var decdata = drsa.Decrypt(encryptedData, false); // Here, I see some exception.
someString = Encoding.ASCII.GetString(decdata);
}
Console.WriteLine("someString someString ::: " + someString);
return true;
}
虽然,运行上面的代码我看到了下面的错误。
Unhandled exception. Internal.Cryptography.CryptoThrowHelper+WindowsCryptographicException: Key not valid for use in specified state.
at Internal.NativeCrypto.CapiHelper.ExportKeyBlob(Boolean includePrivateParameters, SafeKeyHandle safeKeyHandle)
at System.Security.Cryptography.RSACryptoServiceProvider.ExportParameters(Boolean includePrivateParameters)
at ConfigUtility.X509Certificate.ReadRSACertificate()
要验证证书,我有以下命令,
certutil -dump MyCertificate.pfx
所以,上面的实用程序给了我下面的输出,
================ Certificate 0 ================
================ Begin Nesting Level 1 ================
Element 0:
Serial Number: 054834637a713ecf
Issuer: CN=MyApplication
NotBefore: 29-05-2020 13:49
NotAfter: 29-05-2025 13:49
Subject: CN=MyApplication
Signature matches Public Key
Root Certificate: Subject matches Issuer
Cert Hash(sha1): 16e83e8a92a38b948adad03a86768e27115851d4
---------------- End Nesting Level 1 ----------------
Provider = Microsoft Software Key Storage Provider
Private key is NOT plain text exportable
Encryption test passed
CertUtil: -dump command completed successfully.
事实上,你在这一行得到了例外:
drsa.FromXmlString(certificate.PrivateKey.ToXmlString(false));
整个加密和解密代码段都不正确,你在乱用旧的已弃用的 RSACryptoServiceProvider
并进行不必要的操作。该方法应如下所示:
public bool EncryptAndDecryptFile() {
string data = "{data: 'mydate123@gmail.com'}";
X509Certificate2 certificate = new X509Certificate2("MyCertificate.pfx", "TestPassword", X509KeyStorageFlags.Exportable);
if (certificate.HasPrivateKey) {
Console.WriteLine("Private key available "); // It's says like the private key was available
}
Byte[] encryptedData = new Byte[0];
using (RSA pubKey = certificate.GetRSAPublicKey()) {
byte[] bytes = Encoding.ASCII.GetBytes(data);
encryptedData = rsa.Encrypt(bytes, RSAEncryptionPadding.OaepSHA256);
}
// assuming, encryptedData is not null
String someString = String.Empty;
using (RSA prKey = certificate.GetRSAPrivateKey()) {
Byte[] decdata = prKey.Decrypt(encryptedData, RSAEncryptionPadding.OaepSHA256);
someString = Encoding.ASCII.GetString(decdata);
}
return data.Equals(someString);
}