2011-02-08 6 views
9

Per accedere al servizio web ho bisogno di un certificato.Conservare il certificato X509 nella banca dati

ho generato certificati personali:

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

poi fuse questi due in un certificato PFX da

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

poi caricato il mio file pfx come X509Certificate2

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

ora, vorrei piace creare una tabella nel database che contenga i seguenti campi:

Quindi copiare il contenuto dal file private.key, insieme a ----- INIZIO CERTIFICATO ----- e ----- CERTIFICATO DI FINE -----, lo stesso per public.cer e impostare la password. Ora, come posso ottenere un'istanza corretta di X509Certificate2 leggendo questi dati dal DB? In altre parole, come posso generare un file pfx dal codice, basato su chiave privata e certificato?

cercherò di essere più precisi:

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

Questo codice correttamente caricare una stringa di certificato (certificato x509, a partire ----- BEGIN CERTIFICATE ----- e termina --- --END CERTIFICATO -----).

Ora ho bisogno di ottenere la chiave privata:

La mia chiave privata è in formato RSA (----- BEGIN chiave privata RSA ---- ecc ...)

ho bisogno di caricarlo e assegnarlo a serverCert, per poter utilizzare questo certificato per l'autenticazione sul servizio web.

Qualche suggerimento su come farlo?

+0

La risposta a questo problema si trova qui. http://www.codeproject.com/KB/security/CertificatesToDBandBack.aspx Riguarda –

+0

Correlati: https://stackoverflow.com/questions/893757 – explunit

risposta

4

Si dispone di un costruttore con un byte []. Così è possibile memorizzare il certificato come un array di byte e caricare il certificato con

public X509Certificate2(
    byte[] rawData 
) 

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

+0

Questo non è applicabile al mio caso. Devo poter consentire al client di generare private.key e il certificato pubblico, quindi è necessario copiare il contenuto di questi due file nel DB e salvare la password per una chiave privata anche nel DB. Ora, sulla base di questi dati, dal codice, ho bisogno di creare un oggetto X509Certificate2 valido. –

+0

@MaiO: questo è un dettaglio che dovresti includere nella tua domanda. Ad ogni modo, le cose tra '----- BEGIN CERTIFICATE -----' e '----- END CERTIFICATE -----' sono solo dati codificati Base64. Un buon punto di partenza potrebbe essere l'esecuzione del testo tramite 'Covert.FromBase64String()'. – josh3736

+0

In realtà non sembra funzionare, nonostante ciò che dice la documentazione. L'errore è CryptographicException: impossibile trovare l'oggetto richiesto – r590

6

Quindi questo è in realtà facile, anche se ho trovato nessuna semplice descrizione di esso. Ho lasciato le corde cert nel mio Gist (cert campione, non ci sono dati sicuri)

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