2012-09-15 7 views
5

Ho creato la mia auto firmato la certificazione e installato alla radice attendibili del mio cliente e utilizzato per pfx [lato server] per confermare che la certificazione e l'autenticazione è in corso senza intoppi, senza erroriÈ possibile a chiunque creare una certificazione falsa?

Ma c'è una domanda che realmente mi confonde c'è un modo per un hacker di falsificare l'autenticazione con il mio cliente? con il suo falso certificato e server?

Esempio:

Il mio codice per convalidare la certificazione è

private static bool OnCertificateValidation(
     object sender, 
     X509Certificate certificate, 
     X509Chain chain, 
     SslPolicyErrors sslPolicyErrors) 
    { 
     if (sslPolicyErrors == SslPolicyErrors.None) 
     { 
      if (CaVerify(chain) && ServerVerify(certificate)) return true; 
     } 
     return false; 
    } 

    public static bool CaVerify(X509Chain chain) 
    { 
     if (chain.ChainElements.Count > 0) 
     { 
      var certHash = chain.ChainElements[chain.ChainElements.Count - 1].Certificate.GetCertHash(); 
      if (certHash.Length == ApiCertHash.Length) 
      { 
       for (var idx = 0; idx < certHash.Length; idx++) 
       { 
        if (certHash[idx] == ApiCertHash[idx]) 
        { 
         return true; 
        } 
       } 
      } 
     } 
     return false; 
    } 

    public static bool ServerVerify(X509Certificate certificate) 
    { 
     var certHash = certificate.GetCertHash(); 

     if (certHash.Length == ApiCertHash.Length) 
     { 
      for (var idx = 0; idx < certHash.Length; idx++) 
      { 
       if (certHash[idx] == ApiCertHash[idx]) 
       { 
        return true; 
       } 
      } 

     } 
     return false; 
    } 

Così qualcuno potrebbe creare un certification.pfx falso e associarlo al suo server di falso e collegare il mio cliente al suo server di falso?

risposta

4

Il campo Nome comune (CN) del certificato SSL deve essere il nome DNS dell'host a cui si sta tentando di connettersi. Si sta "Fidati" del "Trusted Autorità di certificazione radice" che non emetteranno un certificato con una CN senza convalida della proprietà del nome DNS elencato nella CN.

Si è aggirato questo aggiungendo manualmente un'autorità di certificazione (CA) all'elenco di fiducia. Quindi il computer si fida della CA personale che il certificato ricevuto dal server sia autorizzato a essere utilizzato per qualsiasi CN elencato nel certificato.

Un utente malintenzionato non può creare un certificato "falso" poiché la CA che ha emesso il certificato non autorizzato non è "attendibile", pertanto la convalida non riesce.


Ecco come funzionano spesso i proxy coperti. Il reparto IT installa una CA sulle workstation. Quando si effettua una richiesta SSL passa attraverso il proxy, quando la risposta ritorna il proxy intercetta "CN=*.google.com Firmato da VeriSign" e invia alla workstation "CN=*.google.com, Firmato da XYZ Corperate Proxy". Poiché l'IT preinstallata CA attendibile, il browser non si lamenta.

Tuttavia, se si utilizza un browser che non utilizza il negozio normale o non ha installato CA, si otterrebbe un errore di certificato poiché il computer visualizzerebbe il certificato "Firmato da XYZ Coperate Proxy", non si sa chi sia CA è, quindi restituire RemoteCertificateChainErrors sull'argomento sslPolicyErrors.


Esempio di codice di controllo dell'hash della CA.

if (sslPolicyErrors == SslPolicyErrors.None) 
{ 
    var apiCertHash = new byte[] { 0x79, 0x04, 0x15, 0xC5, 0xC4, 0xF1, 0x6A, 0xA7, 0xC9, 0x12, 0xBB, 0x23, 0xED, 0x5A, 0x60, 0xA7, 0x92, 0xA8, 0xD5, 0x94 }; 
    if(chain.ChainElements.Count > 0) 
    { 
     //Not 100% if the root is first or last in the array. Don't have the program running to check. 
     var certHash = chain.ChainElements[chain.ChainElements.Count - 1].Certificate.GetCertHash(); 
     if (certHash.Length == apiCertHash.Length) 
     { 
      for (var idx = 0; idx < certHash.Length; idx++) 
      { 
       if (certHash[idx] == apiCertHash[idx]) 
       { 
        return true; 
       } 
      } 
     } 
    } 
} 
+0

Sì che può, * sulla sua macchina solo * . Questo non sarebbe un "Main In the Middle", l'attaccante controlla un endpoint, non c'è molto che tu possa fare al riguardo. Puoi inserire l'impronta digitale del certificato, ma un'idea più intelligente sarebbe inserire l'impronta digitale della CA e controllare che, in questo modo, puoi emettere nuovi certificati (ad esempio, devi cambiare il nome DNS a cui ti stai connettendo, bisogno di un nuovo certificato e quindi di una nuova impronta digitale). Aggiungerò del codice veloce per mostrare come. –

+0

Quindi Ssl serve solo per proteggere il mio client-server dall'attacco MITM ma non per controllare l'EndPoint del mio client? –

+0

Non è possibile proteggere l'endpoint. Se l'utente finale può eseguire codice arbitrario, hai perso. Tutto ciò che un utente malintenzionato deve fare è collegare il proprio debugger e possono fare tutto ciò che vogliono con il programma in esecuzione. Puoi renderlo duro con loro, ma non puoi fermarlo. L'unico modo per "fermarlo" è che l'utente finale non deve poter eseguire tutto ciò che desidera. Un esempio di questo è un iPhone ** non-jailbroken **, un utente può eseguire solo app dall'app store e il negozio non ha strumenti di debug, quindi l'utente finale non può attaccare il programma. Ma se jailbroken ... sei dove hai iniziato, non puoi fermarlo. –

1

Se avete intenzione di utilizzare il certificato auto-firmato, è necessario utilizzare il codice è presentato altrimenti è sufficiente utilizzare solo

private static bool OnCertificateValidation(
    object sender, 
    X509Certificate certificate, 
    X509Chain chain, 
    SslPolicyErrors sslPolicyErrors) 
{ 
    if (sslPolicyErrors == SslPolicyErrors.None) 
    { 
     return true; 

    } 
    return false; 
} 
Problemi correlati