2011-02-08 21 views
9

Para acceder al servicio web necesito un certificado.Tienda X509 Certificado en la base de datos

que generan mis certificados:

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

vez fusionada este dos en un certificado PFX por

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

continuación, se carga mi archivo PFX como X509Certificate2

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

Ahora, lo haría desea crear una tabla en la base de datos que contiene los siguientes campos:

PrivateKey NVARCHAR 
PublicCer NVARCHAR 
Password NVARCHAR 

A continuación, copie el contenido del archivo private.key, junto con ----- BEGIN CERTIFICATE ----- y ----- END CERTIFICATE -----, lo mismo para el public.cer y establece la contraseña Ahora, ¿cómo puedo obtener una instancia adecuada de X509Certificate2 leyendo estos datos de DB? En otras palabras, ¿cómo puedo generar un archivo pfx a partir de código, basado en clave privada y certificado?

Voy a tratar de ser más precisos:

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

Este código se carga correctamente una cadena de certificado (certificado X509, empezando por ----- BEGIN CERTIFICATE ----- y terminando --- - CERTIFICADO ENVIADO -----).

Ahora necesito para obtener la clave privada:

mi clave privada está en formato RSA (----- BEGIN la clave privada RSA ---- etc ...)

Necesito cárguelo y asígnelo a serverCert, para poder usar este certificado para autenticarse en el servicio web.

¿Alguna sugerencia sobre cómo hacer eso?

+0

La respuesta a este problema se encuentra aquí. http://www.codeproject.com/KB/security/CertificatesToDBandBack.aspx Saludos –

+0

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

Respuesta

4

Tiene un constructor con un byte []. Para que pueda almacenar su certificado como una matriz de bytes y cargar su certificado con

public X509Certificate2(
    byte[] rawData 
) 

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

+0

Esto no se aplica a mi caso. Necesito poder permitir que el cliente genere private.key y el certificado público, luego debe copiar el contenido de estos dos archivos en el DB y guardar la contraseña para una clave privada también en el DB. Ahora, en base a estos datos, desde el código, necesito crear un objeto válido X509Certificate2. –

+0

@MaiO: este es un detalle que debe incluir en su pregunta. En cualquier caso, las cosas entre '----- BEGIN CERTIFICATE -----' y '----- END CERTIFICATE -----' son solo datos codificados en Base64. Un buen lugar para comenzar podría ser ejecutar el texto a través de 'Covert.FromBase64String()'. – josh3736

+0

Esto en realidad no parece funcionar, a pesar de lo que dice la documentación. El error es CryptographicException: no se puede encontrar el objeto solicitado – r590

6

así que esto es realmente fácil, aunque no he encontrado ninguna descripción simple de la misma. He dejado las cuerdas en mi cert GIST (CERT muestra, no hay datos seguros)

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