web-dev-qa-db-fra.com

Associez une clé privée à la classe X509Certificate2 dans .net

Je travaille sur un code qui crée un certificat X509 et une paire de clés publique/privée. La clé publique est ajoutée au certificat et envoyée à une autorité de certification qui le signe.

Le certificat retourné est ensuite accessible via la classe System.Security.Cryptography.X509Certificates.X509Certificate2. Maintenant, je veux utiliser ce certificat pour établir une connexion sécurisée avec d'autres clients. Par conséquent, j'utilise la classe SslStream. Pour démarrer la prise de contact SSL, j'utilise cette méthode:

server.AssociatedSslStream.AuthenticateAsServer(
                        MyCertificate,                      // Client Certificate
                        true,                               // Require Certificate from connecting Peer
                        SslProtocols.Tls,                   // Use TLS 1.0
                        false                               // check Certificate revocation
                    );

Cette méthode nécessite que la clé privée soit associée au certificat. Bien entendu, le certificat renvoyé par l'autorité de certification ne contient pas de clé privée. Mais il est stocké sous forme de fichier .key sur le disque dur. La classe X509Certificate2 possède une propriété appelée PrivateKey qui, je suppose, associera une clé privée au certificat, mais je ne trouve pas de moyen de définir cette propriété.

Existe-t-il un moyen d'associer la clé privée à la classe .net X509?

19
PogoMips

Pour tous les autres ayant le même problème, j'ai trouvé un petit morceau de code qui vous permet de faire exactement cela:

http://www.codeproject.com/Articles/162194/Certificates-to-DB-and-Back

byte[] certBuffer = Helpers.GetBytesFromPEM(publicCert, PemStringType.Certificate);
byte[] keyBuffer  = Helpers.GetBytesFromPEM(privateKey, PemStringType.RsaPrivateKey);

X509Certificate2 certificate = new X509Certificate2(certBuffer, password);

RSACryptoServiceProvider prov = Crypto.DecodeRsaPrivateKey(keyBuffer);
certificate.PrivateKey = prov;

EDIT: Le code de la méthode Helper (qui nécessite autrement une connexion au projet de code) est le suivant:

public static byte[] GetBytesFromPEM(string pemString, PemStringType type)
{
    string header; string footer;
    switch (type)
    {
        case PemStringType.Certificate:
            header = "-----BEGIN CERTIFICATE-----";
            footer = "-----END CERTIFICATE-----";
            break;
        case PemStringType.RsaPrivateKey:
            header = "-----BEGIN RSA PRIVATE KEY-----";
            footer = "-----END RSA PRIVATE KEY-----";
            break;
        default:
            return null;
    }

    int start = pemString.IndexOf(header) + header.Length;
    int end = pemString.IndexOf(footer, start) - start;
    return Convert.FromBase64String(pemString.Substring(start, end));
}
17
PogoMips

Vous pouvez vous épargner les tracas de copier-coller tout ce code et stocker la clé privée à côté du certificat dans un pfx/pkcs#12 fichier:

openssl pkcs12 -export -in my.cer -inkey my.key -out mycert.pfx

Vous devrez fournir un mot de passe, que vous devrez transmettre au constructeur de X509Certificate2:

X509Certificate2 cert = new X509Certificate2("mycert.pfx","password");
35
sschober