2012-09-15 23 views
5

He creado mi auto-certificación firmada e instalado a raíz de confianza de mi cliente y se utiliza para .PFX [servidor] para confirmar que la certificación y la autenticación se va sin problemas, sin ningún error¿Es posible que alguien cree una certificación falsa?

Pero hay una pregunta que realmente me confunde ¿hay alguna forma de que un hacker falsifique la autenticación con mi cliente? con su falso certificado y servidor?

Ejemplo:

Mi código para validar la certificación es

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

Así Podría alguien crear un certification.pfx falso y asociarlo a su servidor falso y conectarse a mi cliente a su servidor falso?

Respuesta

4

El campo Nombre común (CN) del certificado SSL debe ser el nombre DNS del host al que está intentando conectarse. Está "Confiando" en "Trusted Root Certificate Authorites" que no emitirán un certificado con un CN sin validar la propiedad del nombre DNS enumerado en el CN.

Ha omitido esto agregando manualmente una Autoridad de certificación (CA) a la lista de confianza. Por lo tanto, la computadora confía en su CA personal que el certificado que recibió del servidor está autorizado para ser utilizado para cualquier CN enumerado en el certificado.

Un atacante no puede hacer un certificado "falso" ya que la CA que emitió el certificado no autorizado no es "de confianza", por lo que la validación falla.


Así es como funcionan los proxies a menudo. El departamento de TI instala una CA en las estaciones de trabajo. Cuando realiza una solicitud SSL pasa por el proxy, cuando la respuesta vuelve, el proxy intercepta "CN=*.google.com Firmado por VeriSign" y lo envía a su estación de trabajo "CN=*.google.com, Firmado por XYZ Corperate Proxy". Como el IT preinstaló la CA raíz de confianza, el navegador no se queja.

Sin embargo, si usa un navegador que no utiliza la tienda normal o CA no tiene instalado, obtendrá un error de certificado ya que su computadora vería el certificado "Firmado por XYZ Coperate Proxy", no sabría quién era esa CA es, luego devuelve RemoteCertificateChainErrors en el argumento sslPolicyErrors.


Ejemplo de código de comprobación del hash de 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í que puede, * en su máquina sólo * . Eso no sería un "Principal en el medio", el atacante controla un punto final, no hay mucho que puedas hacer al respecto. Puedes poner la huella digital del certificado, pero una idea más inteligente sería colocar la huella digital de la CA y verificar que, de esa manera, puedas emitir nuevos certificados (digamos que necesitas cambiar el nombre DNS al que te estás conectando, lo harías necesita un nuevo certificado y, por lo tanto, una nueva huella digital cert). Añadiré un código rápido para mostrar cómo. –

+0

¿Entonces Ssl es solo para proteger mi cliente-servidor del ataque MITM pero no para controlar el EndPoint de mi cliente? –

+0

Es imposible proteger el punto final. Si el usuario final puede ejecutar código arbitrario, ha perdido. Todo lo que un atacante tiene que hacer es adjuntar su propio depurador y pueden hacer lo que quieran con el programa en ejecución. Puedes hacer que sea difícil para ellos, pero no puedes detenerlo. La única forma de "detenerlo" es que el usuario final no debe tener permitido ejecutar lo que quiera. Un ejemplo de esto es un iPhone ** sin jailbreak **, un usuario solo puede ejecutar aplicaciones desde la tienda de aplicaciones, y la tienda no tiene herramientas de depuración, por lo que el usuario final no puede atacar el programa. Pero si está en jailbreak ... está donde comenzó, no puede detenerlo. –

1

Si va a utilizar su certificado autofirmado, es necesario utilizar el código que presentan por lo demás es suficiente para usar solo

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

    } 
    return false; 
} 
Cuestiones relacionadas