Хранить сертификат X509 в базе данных - PullRequest
9 голосов
/ 08 февраля 2011

Для доступа к веб-сервису мне нужен сертификат.

Я сгенерировал свои сертификаты:

openssl genrsa 1024 > private.key
openssl req -new -x509 -nodes -sha1 -days 1100 -key private.key > public.cer

, а затем слил эти два в сертификат pfx с помощью

openssl pkcs12 -in public.cer -inkey private.key -export -out client.pfx

затем загрузил мой pfx-файл как X509Certificate2

X509Certificate2 clientCert = new X509Certificate2("cert.pfx", "password");

Теперь я хотел бы создать таблицу в базе данных, которая содержит следующие поля:

PrivateKey NVARCHAR  
PublicCer NVARCHAR  
Password NVARCHAR  

Затем скопируйтесодержимое файла private.key вместе с ----- BEGIN CERTIFICATE ----- и ----- END CERTIFICATE -----, то же самое для public.cer, и установите пароль.Теперь, как я могу получить правильный экземпляр X509Certificate2, читая эти данные из БД?Другими словами, как я могу сгенерировать файл pfx из кода на основе закрытого ключа и сертификата?

Я постараюсь быть более точным:

 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));

Этот код будет правильно загружатьстрока сертификата (сертификат x509, начинающийся с ----- BEGIN CERTIFICATE ----- и заканчивающийся ----- END CERTIFICATE -----).

Теперь мне нужно получить закрытый ключ:

Мой закрытый ключ в формате RSA (----- НАЧАТЬ RSA ЧАСТНЫЙ КЛЮЧ ---- и т. Д.)

Мне нужно загрузить его и назначить на serverCert, чтобы можно было использовать этот сертификат для аутентификации на веб-сервисе.

Есть предложения о том, как это сделать?

Ответы [ 2 ]

6 голосов
/ 22 апреля 2013

Так что на самом деле это легко, хотя я не нашел простого описания этого.Я оставил строки сертификата в своей сущности (образец сертификата, без защищенных данных)

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);
 }
4 голосов
/ 08 февраля 2011

У вас есть конструктор с байтом [].Таким образом, вы можете сохранить свой сертификат в виде байтового массива и загрузить свой сертификат с помощью ссылки

public X509Certificate2(
    byte[] rawData
)

: http://msdn.microsoft.com/en-us/library/ms148413%28v=VS.100%29.aspx

...