tiempo solucion solicitud seguridad que operación nombre instancia espera error datos correcto conexión conecta compruebe cifrado agotado c# ssl ssl-certificate sslstream

c# - solucion - sql server no conecta



¿Utiliza SSL y SslStream para la autenticación de igual a igual? (3)

Necesito proporcionar comunicación segura entre varios procesos que usan conectores TCP / IP para la comunicación. Quiero autenticación y encriptación. En lugar de reinventar la rueda, realmente me gustaría utilizar SSL y la clase SslStream y certificados autofirmados. Lo que quiero hacer es validar el certificado del proceso remoto con una copia conocida en mi aplicación local. (No es necesario que haya una autoridad de certificación porque pretendo que los certificados se copien de forma manual).

Para hacer esto, quiero que la aplicación pueda generar automáticamente un nuevo certificado la primera vez que se ejecuta. Además de makecert.exe, parece que este enlace muestra una forma de generar automáticamente certificados autofirmados, por lo que es un comienzo.

He observado los métodos AuthenticateAsServer y AuthenticateAsClient de SslStream. Puede proporcionar call-backs para verificación, por lo que parece que es posible. Pero ahora que conozco los detalles, realmente no creo que sea posible hacer esto.

¿Voy en la dirección correcta? ¿Hay una mejor alternativa? ¿Alguien ha hecho algo como esto antes (básicamente SSL de igual a igual en lugar de cliente-servidor)?


Lo que propones me parece bien, excepto que parece que esperas hasta que se invoque la devolución de llamada para generar el certificado. No creo que eso vaya a volar; AFAIK, debe proporcionar un certificado válido cuando invoque AuthenticateAsX .

Sin embargo, estas clases son invalidables; entonces, en teoría, podría crear una clase derivada que primero verifique si un certificado necesita ser generado, lo genera si es necesario, luego invoca el método padre AuthenticateAsX .


Puede ver también este ejemplo Ejemplo Asincrónico SslStream Implementación cliente / servidor http://blogs.msdn.com/joncole/archive/2007/06/13/sample-asynchronous-sslstream-client-server-implementation.aspx

si el certificado no se produce correctamente, puede obtener una excepción. El modo de servidor SSL debe usar un certificado con la clave privada asociada.

ejemplo de certificado básico

makecert -sr LocalMachine -ss My -n CN = Test -sky exchange -sk 123456

o

como archivo externo

makecert -sr LocalMachine -ss My -n CN = Test -sky exchange -sk 123456 c: / Test.cer

Herramienta de creación de certificado (Makecert.exe)
http://msdn.microsoft.com/en-us/library/bfsktky3%28VS.80%29.aspx


Paso 1: generar un certificado autofirmado:

  • Descargué la clase de Certificate.cs publicada por Doug Cook
  • Usé este código para generar un archivo de certificado .pfx:

    byte[] c = Certificate.CreateSelfSignCertificatePfx( "CN=yourhostname.com", //host name DateTime.Parse("2000-01-01"), //not valid before DateTime.Parse("2010-01-01"), //not valid after "mypassword"); //password to encrypt key file using (BinaryWriter binWriter = new BinaryWriter( File.Open(@"testcert.pfx", FileMode.Create))) { binWriter.Write(c); }

Paso 2: cargando el certificado

X509Certificate cert = new X509Certificate2( @"testcert.pfx", "mypassword");

Paso 3: armarlo

  • Lo basé en este ejemplo muy simple de SslStream
  • Obtendrá un error de tiempo de compilación sobre la enumeración SslProtocolType. Simplemente cambie eso de SslProtocolType.Default a SslProtocols.Default
  • Hubo 3 advertencias sobre las funciones en desuso. Los reemplacé a todos con los reemplazos sugeridos.
  • Reemplacé esta línea en el archivo Server Program.cs con la línea del Paso 2:

    X509Certificate cert = getServerCert ();

  • En el archivo Client Program.cs, asegúrese de establecer serverName = yourhostname.com (y que coincida con el nombre en el certificado)

  • En el Client Program.cs, la función CertificateValidationCallback falla porque sslPolicyErrors contiene un RemoteCertificateChainErrors. Si profundiza un poco más, esto se debe a que la autoridad emisora ​​que firmó el certificado no es una raíz confiable.
  • No quiero que el usuario importe certificados en la tienda raíz, etc., así que hice un caso especial para esto y verifico ese certificado. GetPublicKeyString () es igual a la clave pública que tengo en el archivo para ese servidor. Si coincide, devuelvo True de esa función. Eso parece funcionar.

Paso 4: Autenticación del cliente

Así es como mi cliente se autentica (es un poco diferente al servidor):

TcpClient client = new TcpClient(); client.Connect(hostName, port); SslStream sslStream = new SslStream(client.GetStream(), false, new RemoteCertificateValidationCallback(CertificateValidationCallback), new LocalCertificateSelectionCallback(CertificateSelectionCallback)); bool authenticationPassed = true; try { string serverName = System.Environment.MachineName; X509Certificate cert = GetServerCert(SERVER_CERT_FILENAME, SERVER_CERT_PASSWORD); X509CertificateCollection certs = new X509CertificateCollection(); certs.Add(cert); sslStream.AuthenticateAsClient( serverName, certs, SslProtocols.Default, false); // check cert revokation } catch (AuthenticationException) { authenticationPassed = false; } if (authenticationPassed) { //do stuff }

El CertificateValidationCallback es el mismo que en el caso del servidor, pero tenga en cuenta cómo AuthenticateAsClient toma una colección de certificados, no solo un certificado. Por lo tanto, debe agregar un LocalCertificateSelectionCallback, así (en este caso, solo tengo un certificado de cliente, así que solo devuelvo el primero en la colección):

static X509Certificate CertificateSelectionCallback(object sender, string targetHost, X509CertificateCollection localCertificates, X509Certificate remoteCertificate, string[] acceptableIssuers) { return localCertificates[0]; }