问题
In order to access to the web service I need a certificate.
I generated my certs:
openssl genrsa 1024 > private.key
openssl req -new -x509 -nodes -sha1 -days 1100 -key private.key > public.cer
then merged this two into a pfx certificate by
openssl pkcs12 -in public.cer -inkey private.key -export -out client.pfx
then loaded my pfx file as X509Certificate2
X509Certificate2 clientCert = new X509Certificate2("cert.pfx", "password");
Now, I would like to create a table into the data base that contains the following fields:
PrivateKey NVARCHAR
PublicCer NVARCHAR
Password NVARCHAR
Then copy the content from private.key file, along with -----BEGIN CERTIFICATE----- and -----END CERTIFICATE-----, same for the public.cer, and set the password. Now, how can I get a proper instance of X509Certificate2 by reading this data from DB? In other words, how can I generate a pfx file from code, based on private key and certificate?
I will try to be more precise:
string connectionString; string query; string cert;
connectionString = ConfigurationManager.ConnectionStrings[0].ConnectionString;
query = "SELECT clientcert FROM settings_services WHERE ID = 1";
using (SqlConnection cn = new SqlConnection(connectionString))
{
SqlCommand cmd = new SqlCommand(query, cn);
cn.Open();
cert = (string)cmd.ExecuteScalar();
}
X509Certificate2 serverCert = new X509Certificate2(Encoding.UTF8.GetBytes(cert));
This code will correctly load a certificate string (x509 certificate, starting with -----BEGIN CERTIFICATE----- and ending -----END CERTIFICATE-----).
Now I need to get the private key:
My private key is in RSA format (-----BEGIN RSA PRIVATE KEY---- etc...)
I need to load it, and assign it to serverCert, in order to be able to use this certificate for authenticate on web service.
Any suggestions on how to do that?
回答1:
So this is actually easy, although I found no simple description of it. I've left the cert strings in my gist (sample cert, no secure data)
https://gist.github.com/BillKeenan/5435753
[TestMethod]
public void TestCertificate()
{
const string publicCert = @"MIIBrzCCARigAwIBAgIQEkeKoXKDFEuzql5XQnkY9zANBgkqhkiG9w0BAQUFADAYMRYwFAYDVQQDEw1DZXJ0QXV0aG9yaXR5MB4XDTEzMDQxOTIwMDAwOFoXDTM5MTIzMTIzNTk1OVowFjEUMBIGA1UEAxMLc2VydmVyMS5jb20wgZ0wDQYJKoZIhvcNAQEBBQADgYsAMIGHAoGBAIEmC1/io4RNMPCpYanPakMYZGboMCrN6kqoIuSI1n0ufzCbwRkpUjJplsvRH9ijIHMKw8UVs0i0Ihn9EnTCxHgM7icB69u9EaikVBtfSGl4qUy5c5TZfbN0P3MmBq4YXo/vXvCDDVklsMFem57COAaVvAhv+oGv5oiqEJMXt+j3AgERMA0GCSqGSIb3DQEBBQUAA4GBAICWZ9/2zkiC1uAend3s2w0pGQSz4RQeh9+WiT4n3HMwBGjDUxAx73fhaKADMZTHuHT6+6Q4agnTnoSaU+Fet1syVVxjLeDHOb0i7o/IDUWoEvYATi8gCtcV20KxsQVLEc5jkkajzUc0eyg050KZaLzV+EkCKBafNoVFHoMCbm3n";
const string privateCert = @"<RSAKeyValue><Modulus>gSYLX+KjhE0w8Klhqc9qQxhkZugwKs3qSqgi5IjWfS5/MJvBGSlSMmmWy9Ef2KMgcwrDxRWzSLQiGf0SdMLEeAzuJwHr270RqKRUG19IaXipTLlzlNl9s3Q/cyYGrhhej+9e8IMNWSWwwV6bnsI4BpW8CG/6ga/miKoQkxe36Pc=</Modulus><Exponent>EQ==</Exponent><P>mmRPs28vh0mOsnQOder5fsxKsuGhBkz+mApKTNQZkkn7Ak3CWKaFzCI3ZBZUpTJag841LL45uM2NvesFn/T25Q==</P><Q>1iTLW2zHVIYi+A6Pb0UarMaBvOnH0CTP7xMEtLZD5MFYtqG+u45mtFj1w49ez7n5tq8WyOs90Jq1qhnKGJ0mqw==</Q><DP>JFPWhJKhxXq4Kf0wlDdJw3tc3sutauTwnD6oEhPJyBFoPMcAjVRbt4+UkAVBF8+c07gMgv+VHGyZ0lVqvDmjgQ==</DP><DQ>lykIBEzI8F6vRa/sxwOaW9dqo3fYVrCSxuA/jp7Gg1tNrhfR7c3uJPOATc6dR1YZriE9QofvZhLaljBSa7o5aQ==</DQ><InverseQ>KrrKkN4IKqqhrcpZbYIWH4rWoCcnfTI5jxMfUDKUac+UFGNxHCUGLe1x+rwz4HcOA7bKVECyGe6C9xeiN3XKuQ==</InverseQ><D>Fsp6elUr6iu9V6Vrlm/lk16oTmU1rTNllLRCZJCeUlN/22bHuSVo27hHyZ1f+Q26bqeL9Zpq7rZgXvBsqzFt9tBOESrkr+uEHIZwQ1HIDw2ajxwOnlrj+zjn6EKshrMOsEXXbgSAi6SvGifRC2f+TKawt9lZmGElV4QgMYlC56k=</D></RSAKeyValue>";
var certificate = new X509Certificate2(Convert.FromBase64String(publicCert));
var crypto = new RSACryptoServiceProvider();
crypto.FromXmlString(privateCert);
certificate.PrivateKey = crypto;
//export a private key
var exportedPrivate = certificate.PrivateKey.ToXmlString(true);
var exportedPublic = Convert.ToBase64String(certificate.RawData);
Assert.AreEqual(publicCert, exportedPublic);
Assert.AreEqual(privateCert, exportedPrivate);
}
回答2:
You have a constructor with a byte[]. So you can store your certificate as a byte array and load your certificate with
public X509Certificate2(
byte[] rawData
)
link: http://msdn.microsoft.com/en-us/library/ms148413%28v=VS.100%29.aspx
来源:https://stackoverflow.com/questions/4933759/store-x509-certificate-in-database