2011-10-08 16 views
7

Ho generato una CA e più certificati (firmati da CA) utilizzando OpenSSL e ho un client/server .NET/C# entrambi utilizzando SslStream ciascuno con i propri certificati/chiavi, l'autenticazione reciproca è abilitata e la revoca è disabilitata.Verifica server remoto X509Certificato utilizzando il file certificato CA

Sto usando RemoteCertificateValidationCallback per SslStream per convalidare il certificato del server remoto e speravo di poter caricare il certificato pubblico della CA (come un file) nel programma e utilizzarlo per verificare il certificato remoto piuttosto che effettivamente l'installazione del CA nell'archivio certificati di Windows. Il problema è che il X509Chain non mostrerà nient'altro a meno che non installi la CA nell'archivio, sia la shell di Windows CryptoAPI quando apro una versione PEM di uno dei certificati.

La mia domanda è, come posso verificare un certificato è stato firmato da mio specifico CA semplicemente utilizzando file del certificato pubblico della CA senza l'utilizzo di certificati di Windows o WCF quando RemoteCertificateValidationCallback, X509Certificate e X509Chain non sembrano dare ho qualcosa con cui lavorare?

+1

Non capisco perché l'aggiunta del certificato CA a Windows Store induca X509Chain a mostrarlo nella catena, ma se non lo faccio non ne fa parte. C'è qualcuno per aggiungere il certificato CA alla catena all'interno di RemoteCertificateValidationCallback? – user985122

+0

Ancora non riesco a trovare una risposta a questa :( – user985122

risposta

5

Poiché il certificato CA non è nell'archivio certificati radice, si avrà all'interno del RemoteCertificateValidationCallback() un flag di errore di SslPolicyErrors.RemoteCertificateChainErrors; una possibilità è di convalidare esplicitamente la catena di certificati contro il proprio codice X509Certificate2Collection, poiché non si sta utilizzando lo store locale.

if (sslPolicyErrors == SslPolicyErrors.RemoteCertificateChainErrors) 
{ 
    X509Chain chain0 = new X509Chain(); 
    chain0.ChainPolicy.RevocationMode = X509RevocationMode.NoCheck; 
    // add all your extra certificate chain 
    chain0.ChainPolicy.ExtraStore.Add(new X509Certificate2(PublicResource.my_ca)); 
    chain0.ChainPolicy.VerificationFlags = X509VerificationFlags.AllowUnknownCertificateAuthority; 
    isValid = chain0.Build((X509Certificate2)certificate); 
} 

È inoltre possibile riutilizzare la catena passato nella richiamata, aggiungere il certificato in più (s) nella collezione ExtraStore, e convalidare con il bandierina AllowUnknownCertificateAuthority che è necessario dal momento che si aggiunge non attendibile certificato (i) alla catena.

Si potrebbe anche impedire l'errore originale con l'aggiunta di programmazione il certificato CA nella principale attendibile (naturalmente si apre un popup, perché è un grave problema di sicurezza a livello globale aggiungere una nuova radice CA attendibile):

var store = new X509Store(StoreName.Root, StoreLocation.CurrentUser); 
store.Open(OpenFlags.ReadWrite); 
X509Certificate2 ca_cert = new X509Certificate2(PublicResource.my_ca); 
store.Add(ca_cert); 
store.Close(); 
+0

Un'altra possibilità è usare la libreria 'BouncyCastle' per costruire la catena di certificati e convalidare la fiducia.Le opzioni sono chiare e gli errori sono facili da capire –

+0

Vedere la risposta http : //stackoverflow.com/a/27310276/1038496 qui per un controllo corretto della propria CA. Il metodo sopra riportato accetterà tutte le CA (senza controlli di validità) – Zoka

1

Come posso verificare un certificato è stato firmato da mio specifico CA semplicemente utilizzando file del certificato pubblico della CA senza utilizzare certificati di Windows o WCF quando RemoteCertificateValidationCallback, X509Certificate e X509Chain non sembrano darmi qualsiasi cosa per lavorare con?

Il seguente codice eviterà gli archivi di certificati Windows e convaliderà la catena. È un po 'diverso dal codice di JB, specialmente nell'uso delle bandiere. Il codice seguente non richiede AllowUnknownCertificateAuthority (ma utilizza X509RevocationMode.NoCheck poiché non ho un CRL).

Il nome della funzione non ha importanza. Sotto, VerifyServerCertificate è lo stesso callback di RemoteCertificateValidationCallback nella classe SslStream. È inoltre possibile utilizzarlo per lo ServerCertificateValidationCallback in ServicePointManager.

static bool VerifyServerCertificate(object sender, X509Certificate certificate, 
    X509Chain chain, SslPolicyErrors sslPolicyErrors) 
{ 
    try 
    { 
     String CA_FILE = "ca-cert.der"; 
     X509Certificate2 ca = new X509Certificate2(CA_FILE); 

     X509Chain chain2 = new X509Chain(); 
     chain2.ChainPolicy.ExtraStore.Add(ca); 

     // Check all properties 
     chain2.ChainPolicy.VerificationFlags = X509VerificationFlags.NoFlag; 

     // This setup does not have revocation information 
     chain2.ChainPolicy.RevocationMode = X509RevocationMode.NoCheck; 

     // Build the chain 
     chain2.Build(new X509Certificate2(certificate)); 

     // Are there any failures from building the chain? 
     if (chain2.ChainStatus.Length == 0) 
      return true; 

     // If there is a status, verify the status is NoError 
     bool result = chain2.ChainStatus[0].Status == X509ChainStatusFlags.NoError; 
     Debug.Assert(result == true); 

     return result; 
    } 
    catch (Exception ex) 
    { 
     Console.WriteLine(ex); 
    } 

    return false; 
} 

ho non capito come utilizzare questa catena (chain2 sotto) per impostazione predefinita in modo tale che non c'è bisogno per la richiamata.Cioè, installalo sul socket ssl e la connessione funzionerà ". E ho non capito come installarlo in modo tale che è passato in callback. Cioè, devo costruire la catena per ogni invocazione del callback. Penso che questi siano difetti architettonici in .Net, ma potrei mancare qualcosa di ovvio.

+0

Sembra ok. La 'chain2' sarà la lista di certificato di fiducia tra il certificato testato e il certificato radice. Al giorno d'oggi, potresti voler usare la libreria BouncyCastle se esegui operazioni avanzate sui certificati. –

Problemi correlati