2011-02-08 48 views
9

Để truy cập vào dịch vụ web, tôi cần chứng chỉ.Lưu trữ Chứng chỉ X509 trong cơ sở dữ liệu

tôi tạo Certs tôi:

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

sau đó sáp nhập hai này thành một giấy chứng nhận PFX bởi

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

sau đó nạp tập tin PFX tôi như X509Certificate2

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

Bây giờ, tôi sẽ muốn tạo bảng vào cơ sở dữ liệu chứa các trường sau:

PrivateKey NVARCHAR 
PublicCer NVARCHAR 
Password NVARCHAR 

Sau đó sao chép nội dung từ tệp private.key, cùng với ----- BEGIN GIẤY CHỨNG NHẬN ----- và ----- GIẤY CHỨNG NHẬN -----, tương tự cho public.cer và đặt mật khẩu. Bây giờ, làm thế nào tôi có thể có được một trường hợp thích hợp của X509Certificate2 bằng cách đọc dữ liệu này từ DB? Nói cách khác, làm cách nào để tạo tệp pfx từ mã, dựa trên khóa cá nhân và chứng chỉ?

Tôi sẽ cố gắng để được chính xác hơn:

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

Mã này sẽ được tải một cách chính xác một chuỗi chứng chỉ (chứng chỉ x509, bắt đầu với ----- BEGIN CERTIFICATE ----- và kết thúc --- --END CHỨNG NHẬN -----).

Bây giờ tôi cần phải nhận được khóa bí mật:

khóa riêng của tôi là ở định dạng RSA (----- BEGIN RSA PRIVATE KEY ---- vv ...)

tôi cần phải tải nó và gán nó cho serverCert, để có thể sử dụng chứng chỉ này để xác thực trên dịch vụ web.

Bất kỳ đề xuất nào về cách thực hiện điều đó?

+0

Câu trả lời cho vấn đề này bạn sẽ tìm thấy nó ở đây. http://www.codeproject.com/KB/security/CertificatesToDBandBack.aspx Kính trọng –

+0

Liên quan: https://stackoverflow.com/questions/893757 – explunit

Trả lời

4

Bạn có hàm tạo với byte []. Vì vậy, bạn có thể lưu trữ chứng chỉ của bạn như là một mảng byte và tải chứng chỉ của bạn với

public X509Certificate2(
    byte[] rawData 
) 

liên kết: http://msdn.microsoft.com/en-us/library/ms148413%28v=VS.100%29.aspx

+0

Điều này không áp dụng cho trường hợp của tôi. Tôi cần để có thể cho phép khách hàng tạo ra private.key và cert công cộng, sau đó ông cần phải sao chép nội dung của hai tập tin vào DB và lưu mật khẩu cho một khóa riêng cũng vào DB. Bây giờ, dựa trên những dữ liệu này, từ mã, tôi cần tạo một đối tượng X509Certificate2 hợp lệ. –

+0

@MaiO: Đây là chi tiết bạn nên đưa vào câu hỏi của mình. Ở bất kỳ tỷ lệ nào, nội dung giữa '----- BEGIN CERTIFICATE -----' và '----- END CERTIFICATE -----' chỉ là dữ liệu được mã hóa Base64. Một nơi tốt để bắt đầu có thể chạy văn bản thông qua 'Covert.FromBase64String()'. – josh3736

+0

Điều này dường như không hoạt động, mặc dù tài liệu nói gì. Lỗi là CryptographicException: Không thể tìm thấy đối tượng được yêu cầu – r590

6

Vì vậy, đây thực sự là dễ dàng, mặc dù tôi không tìm thấy mô tả đơn giản của nó. Tôi đã rời khỏi dây cert trong ý chính của tôi (mẫu cert, không có dữ liệu an toàn)

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); 
} 
Các vấn đề liên quan