2009-11-09 14 views
10

[Actualización] - Yo también adjuntar archivos de configuración completos, por service, y por client (fuera de aquí, no inundar el tema)Certificado de servicio WCF y la identidad del punto final del lado del cliente: ¿por qué no funciona?

estoy teniendo situación prácticamente idéntica a la descrita en this cuestión, Sin embargo, mi pregunta es algo diferente.

  • estoy usando NetTcpBinding con seguridad conjunto de TransportWithMessageCredential
  • estoy usando la contraseña/nombre de usuario credenciales respaldados por ASP.NET proveedor de
  • Mi servicio se auto alojado en Windows Servicio
  • I do tener en mi punto extremo comportamiento autenticación especificada revocationMode = "NoCheck"

Se requiere que el servicio proporcione un certificado para autenticarse ante los clientes. Eso está bien, acabo de hacer:

<serviceCertificate findValue="***" 
        storeLocation="CurrentUser" 
        storeName="My" 
        x509FindType="FindByThumbprint"/> 

Ahora, un poco imaginaron que ahora el cliente podría llegar a tener

<identity> 
    <certificate encodedValue="encoded certificate"/> 
</identity> 

y será capaz de verificar las credenciales del servicio sin tener ese certificado instalado en la tienda en la máquina del cliente.

me sorprendió to learn que aunque me puse las credenciales de servicio a certificado, WSDL expone

<Identity> 
    <Dns>Foo</Dns> 
</Identity> 

Una vez más, el servicio que puedo establecer la identidad de CertificateReference y conectarlo a un mismo certificado, y luego WSDL exponer la identidad como X509Certificate, pero cuando ejecuto el cliente que ajuste se ignora, y termino con el mensaje de error:

System.ServiceModel.Security.SecurityNegotiationException: CER X.509 tificate CN = xxx no está en la tienda de personas de confianza. El X.509 certificado CN = xxx cadena de construcción falló. El certificado que se usó tiene una cadena de confianza que no se puede verificar . Reemplace el certificado cambie el certificateValidationMode. Una cadena de certificado procesada, pero terminada en un certificado raíz que no es de confianza para el proveedor de confianza.

¿Hay alguna manera de hacer que el cliente use ese valor de config y trabajo sin tener que instalar un certificado de servicio (ni su raíz) en la máquina del cliente?

[ACTUALIZACIÓN] Mientras se ajusta a ninguno certificateValidationMode hará la excepción desaparece, es una solución inaceptable desde el punto de vista de la seguridad.

Hace que el cliente simplemente reconozca que recibe '' algo '' de certificado, sin entrar en detalles. Esto hace posible toda la gama de ataques de hombre en el medio. Todavía no validará la información enviada por el (supuesto) servicio contra el certificado descargado en la configuración.

Respuesta

4

Solución boceto:

1) Definir y registrar una costumbre X509CertificateValidator en el cliente

2) En el método Validar, comparar el certificado dada con la que presenta en EndpointAddress del cliente .Identidad propiedad. El objeto al que hace referencia esta propiedad debe tener el tipo exacto X509CertificateEndpointIdentity.

No probé esta solución, sin embargo tiene mucho sentido para mí.

HTH Pedro

+0

Esto es lo que terminé haciendo. Tengo una pregunta sin embargo, ¿por qué no funciona de la caja? Si el cliente tiene toda la información requerida, y recibe algún certificado de un servicio, es lo más natural que hacer para validar uno contra el otro. ¿Por qué WCF no hace esto? –

+0

Conjetura: por razones de seguridad. Al usar la solución propuesta, la seguridad del proceso de importación de WSDL se vuelve aún más crítica, ya que no se realizará ninguna verificación de certificado adicional cuando se comunique con el servicio. –

+0

Acabo de comenzar una recompensa por mi propia pregunta que parece similar a lo que estás diciendo aquí. Si puede deletrear la solución con más detalle allí, ¡lo agradecería mucho! http://stackoverflow.com/questions/4579666/wcf-newbie-how-to-install-and-use-a-ssl-certificate –

0

Estás corect y casi terminado de configurar la configuración del cliente. Se echa en falta una última cosa (como se menciona en la descripción del error): es necesario establecer la revocationMode a NoCheck en la configuración:

<behaviors> 
    <endpointBehaviors> 
    <behavior name="SecureMessageUserName"> 
     <clientCredentials> 
     <serviceCertificate> 
      <authentication revocationMode="NoCheck"/> 
     </serviceCertificate> 
     </clientCredentials> 
    </behavior> 
    </endpointBehaviors> 
</behaviors> 

Si necesita más detalles, sólo házmelo saber y voy a publicar una configuración de cliente de trabajo completo.

Editar siento por el retraso

También debe agregar el NOCHECK en la configuración del servidor:

<behavior name="X509SecureBehavior"> 
      <serviceMetadata httpGetEnabled="true" /> 
      <serviceDebug includeExceptionDetailInFaults="true" /> 
      <serviceCredentials> 
      <serviceCertificate storeName="My" storeLocation="CurrentUser" x509FindType="FindByThumbprint" findValue="aaaa" /> 
      <clientCertificate> 
       <authentication certificateValidationMode="None" revocationMode="NoCheck" /> 
      </clientCertificate> 
      </serviceCredentials> 
     </behavior> 

también que no incluía la referencia del certificado en la definición del punto final.

+0

Lo siento, me olvidé de mencionar que tengo este conjunto de opciones. Actualicé la pregunta en consecuencia. De todos modos, el certificado parece ser ignorado independientemente de lo que especifique aquí. –

+0

¿podría publicar un archivo de configuración completo? o la parte significativa de ella? – AlexDrenea

+0

Claro que puedo, los vinculé, porque son bastante grandes, y no quiero asustar a personas potencialmente útiles ahogándolos en toneladas de xml –

2

[ACTUALIZACIÓN] Durante el ajuste certificateValidationMode a ninguno se hacer la excepción desaparece, es inaceptable desde solución de seguridad punto de vista.

Hace que el cliente simplemente confirme que recibe '' algo '' de certificado, sin entrar en detalles. Este hace posible toda la gama de hombres en el medio ataques. Todavía no validará la información enviada por el servicio (supuesta) contra el certificado volcado en la configuración.

Usted está equivocado. Esto hará perfectamente. Eso es lo que realmente quiere: su certificado a no sea validado. Todo lo que necesita es establecer la identidad del punto final en el cliente para

<identity> 
    <certificate encodedValue="encoded certificate"/> 
</identity> 

Cuando el cliente se conecta al servidor de WCF comparará los dos certificados y lanzar una excepción si no coinciden. Y estás perfectamente seguro.

El uso de un validador personalizado como Pedro Felix sugerido es completamente innecesario en su caso. Para eso es exactamente la identidad del punto final.

+0

Esto es engañoso: establecer certificateValidationMode en None significa que puede tener cualquier valor codificado y no lo hará ser revisado. –

1

Este es un comentario adicional a mi respuesta anterior. Lo siento, no puedo comentar las respuestas.

Además, usted no necesita establecer cualquier identidad en el servidor. Olvídate de lo que WSDL te dice sobre la identidad del servidor. La identidad de un punto final de servicio remoto es decidida por el cliente durante el tiempo de ejecución. Si el servidor usa SSL, tiene varias identidades: el nombre común del certificado (es decir, una identidad DNS), una identidad de certificado y una identidad RSA (no está seguro de la última). Por lo tanto, puede verificar la identidad del servidor por cualquiera de estos criterios (o por varios de ellos).

2

Lo siento, no puedo comentar otras respuestas.

Acabo de probar esto en .NET 4.0 y puedo confirmar que la respuesta de "Zeratul" es correcta. Establece explícitamente la identidad del servicio en configuración o programáticamente es suficiente para la autenticación del servidor. No es necesario validar el certificado por ningún otro medio (es decir, puede establecer "certificateValidationMode" en "None") ya que está utilizando el último método de validación: la comparación de la huella digital del certificado.

@AlexDrenea

"serviceCertificate" no se utiliza para la validación. Se usa con seguridad de mensajes para cifrar mensajes antes de enviarlos al servidor. Consulte la documentación de Microsoft acerca de esto:

http://msdn.microsoft.com/en-us/library/ms731782.aspx

Cuestiones relacionadas