2014-12-05 21 views
5

Ho applicazioni server/client personalizzate che comunicano tra di loro utilizzando una connessione TCP SSL-encrypted (protocollo personalizzato). Per configurare il certificato del server, ho creato un'autorità di certificazione autofirmata e l'ho usato per firmare un certificato per il server da utilizzare. Sul lato client, vorrei verificare che il certificato del server a cui mi sto collegando sia stato firmato dalla mia CA autofirmata.verificare il certificato del server contro l'autorità certificato auto-firmato

sono stato in grado di ottenere questo lavoro in C++ con boost dando al ssl :: contesto del certificato CA autofirmato utilizzando la funzione load_verify_file(). Vorrei implementare la stessa funzionalità in un client C#, ma la roba SSL .NET sembra essere molto più rigida sulla fiducia dei certificati che non sono presenti nel trust store di Windows.

Ho trovato diverse soluzioni parziali nella mia ricerca intorno finora. Apparentemente X509Chain is the class to use to verify SSL certificates. Ho provato il codice like this ma la catena creata manualmente continua a lamentare che il certificato di root non è affidabile, proprio come la catena originale che viene passata nella funzione di verifica. C'è un'opzione per ignore unknown certificate authorities, ma che sembra voler dire che accetterà qualsiasi certificato auto-firmato, che sicuramente non è quello che voglio.

Questo è il codice che sembra avvicinarsi a quello che voglio, ma come detto sopra, ho il problema che si lamenta ancora del certificato che aggiungo all'Assistente essendo autofirmato. C'è un modo per convincere X509Chain a fidarsi del certificato che gli sto dando?

bool remoteCertificateValidationCallback(
    object sender, X509Certificate certificate, X509Chain chain, 
    SslPolicyErrors sslPolicyErrors) 
{ 
    // make sure certificate was signed by our CA cert 
    X509Chain verify = new X509Chain(); 
    verify.ChainPolicy.ExtraStore.Add(secureClient.CertificateAuthority); // add CA cert for verification 
    //verify.ChainPolicy.VerificationFlags = X509VerificationFlags.AllowUnknownCertificateAuthority; // this accepts too many certificates 
    verify.ChainPolicy.RevocationMode = X509RevocationMode.NoCheck; // no revocation checking 
    verify.ChainPolicy.RevocationFlag = X509RevocationFlag.ExcludeRoot; 
    if (verify.Build(new X509Certificate2(certificate))) 
    { 
     return true; // success? 
    } 
    return false; 
} 

risposta

5

Ho il sospetto che il certificato CA privato non sia installato nel sistema corrente (dove si esegue il codice) o che sia installato in modo errato. Il certificato CA radice DEVE essere installato nel contenitore CA Trusted Root di Stire del computer, non nell'archivio utente corrente. Per impostazione predefinita, X509Chain utilizza l'archivio computer per cercare ancore affidabili.

Inoltre, il codice non eseguire ciò che si desidera. Accetterà e passerà per qualsiasi CA radice di fiducia pubblica. Invece, è necessario confrontare l'ultimo elemento nel X509Chain.ChainElements, indipendentemente dal fatto che il certificato contenuto sia quello che si aspetta (confrontando i valori di identificazione personale). La correzione foolowing dovrebbe applicarsi:

if (verify.Build(new X509Certificate2(certificate))) 
{ 
    return verify.ChainElements[verify.ChainElements.Count - 1] 
     .Certificate.Thumbprint == cacert.thumbprint; // success? 
} 
return false; 

dove cacert è il certificato della CA principale.

+1

lei ha ragione, io non sto installando il certificato CA nel negozio di fiducia. Speravo di evitare di doverlo fare. Ma sembra più probabile che non possa fare ciò che vorrei con gli strumenti integrati di .NET. Ho appena notato [questa domanda] (http://stackoverflow.com/questions/7695438/verify-remote-server-x509certificate-using-ca-certificate-file) in Related che sembra essere quasi identico (non lo fanno specificare se la CA che stanno utilizzando è autofirmata). Non ha una buona risposta. – plasmoidia

+1

'X509Chain.Build' chiama internamente la funzione' CertCreateCertificateChainEngine' che si basa su un archivio di certificati locale per stabilire un trust. È possibile evitare questo requisito rimuovendo la dichiarazione IF esterna e senza utilizzare il risultato del metodo. È sufficiente per la tua domanda esatta – Crypt32

+0

Quindi confrontare le proprietà Thumbprint di due certificati controllerà se sono uguali? Potrebbe funzionare e potrei persino essere in grado di usare la variabile 'chain' che viene passata (che ha la catena corretta dal server). Posso solo controllare che 'chain.ChainStatus' contenga solo' UntrustedRoot' per assicurare che la catena sia valida e non solo che la CA sia appiccicata alla fine? – plasmoidia

Problemi correlati