2010-12-12 14 views
18

Estoy tratando de asegurar una conexión desde una aplicación Java Client/Server que se comunica por Internet. Mi idea era usar sockets SSL con certificados autofirmados y autenticación de cliente. Hice lo siguiente:Java: SSL Clientside Authentication con certificados autofirmados

  • Servidor: Almacén de claves que contiene el nuevo certificado autofirmado. keytool -genkey -kelalg RSA ...
  • Cliente: Tienda de llaves que contiene el nuevo certificado autofirmado. keytool -genkey -kelalg RSA ...
  • Servidor: almacén de confianza que contiene certificado de cliente exportado (del punto de viñeta anterior). keytool -export para exportar certificado de cliente y keytool -import -v -trustcacerts para importarlo en el almacén de confianza del servidor
  • Cliente: almacén de confianza que contiene el certificado de servidor exportado (desde el primer punto). keytool -export para exportación de certificados y keytool -import -v -trustcacerts servidor para importarlo en almacén de confianza del cliente

Trust-almacenes de claves y se fijan correctamente al servidor/cliente. Puedo ver los certificados cargados (información de depuración de SSL). Pero todo esto no funciona. Durante el protocolo de enlace SSL, me sale el siguiente error (información de depuración SSL):

main, WRITE: TLSv1 Handshake, length = 897 
main, READ: TLSv1 Handshake, length = 141 
*** Certificate chain 
*** 
main, SEND TLSv1 ALERT: fatal, description = bad_certificate 
main, WRITE: TLSv1 Alert, length = 2 
main, called closeSocket() 
main, handling exception: javax.net.ssl.SSLHandshakeException: null cert chain 
main, IOException in getSession(): javax.net.ssl.SSLHandshakeException: null cert chain 
javax.net.ssl.SSLPeerUnverifiedException: peer not authenticated 
    at com.sun.net.ssl.internal.ssl.SSLSessionImpl.getPeerCertificateChain(Unknown Source) 
    at sslsocket.Server.getClientDistinguishedName(Server.java:86) 
    at sslsocket.Server.main(Server.java:37) 

Cuando desactivo la autenticación del cliente, que funciona a la perfección.

Realmente agradecería algo de ayuda. ¡Muchas gracias!

A continuación encontrará el, pero la producción total anónima desde el servidor:

Initializing SSL 
*** 
found key for : server 
chain [0] = [ 
[ 
    Version: V3 
    Subject: CN=xxxxxx Server, OU=communication, O=xxxxxx, L=Zuerich, ST=ZH, C=CH 
    Signature Algorithm: SHA1withRSA, OID = 1.2.840.113549.1.1.5 

    Key: Sun RSA public key, 1024 bits 
    modulus: 9487726xxxxxx15617628447913191 
    public exponent: 65537 
    Validity: [From: Thu Dec 09 17:04:05 CET 2010, 
       To: Wed Jul 03 18:04:05 CEST 2109] 
    Issuer: CN=xxxxxx Server, OU=communication, O=xxxxxx, L=Zuerich, ST=ZH, C=CH 
    SerialNumber: [ 4dxxxxxx5] 

] 
    Algorithm: [SHA1withRSA] 
    Signature: 
0000: 6F 06 1D EA E9 DC 5B 5D EC EB 33 D4 47 01 94 1A o.....[]..3.G... 
xxxxxx 
0070: 99 78 C4 31 5F 84 8F 7B C1 2F 10 A1 9F 50 72 A1 .x.1_..../...Pr. 

] 
*** 
adding as trusted cert: 
    Subject: CN=xxxxxx Client, OU=communication, O=xxxxxx, L=Zuerich, ST=ZH, C=CH 
    Issuer: CN=xxxxxx Client, OU=communication, O=xxxxxx, L=Zuerich, ST=ZH, C=CH 
    Algorithm: RSA; Serial number: 0x4xxxxxx0 
    Valid from Thu Dec 09 17:06:56 CET 2010 until Wed Jul 03 18:06:56 CEST 2109 

trigger seeding of SecureRandom 
done seeding SecureRandom 
Opening socket 
Waiting for clients... 
Allow unsafe renegotiation: false 
Allow legacy hello messages: true 
Is initial handshake: true 
Is secure renegotiation: false 
matching alias: server 
main, called closeSocket() 
Allow unsafe renegotiation: false 
Allow legacy hello messages: true 
Is initial handshake: true 
Is secure renegotiation: false 
[read] MD5 and SHA1 hashes: len = 3 
0000: 01 03 01           ... 
[read] MD5 and SHA1 hashes: len = 98 
0000: 00 3C 00 00 00 20 00 00 04 01 00 80 00 00 05 00 .<... .......... 
xxxxxx 
0060: 26 51            &Q 
main, READ: SSL v2, contentType = Handshake, translated length = 75 
*** ClientHello, TLSv1 
RandomCookie: GMT: 1292088238 bytes = { 223,xxxxxx, 81 } 
Session ID: {} 
Cipher Suites: [SSL_RSA_WITH_RC4_128_MD5, SSL_RSA_WITH_RC4_128_SHA, TLS_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_DSS_WITH_AES_128_CBC_SHA, SSL_RSA_WITH_3DES_EDE_CBC_SHA, SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA, SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA, SSL_RSA_WITH_DES_CBC_SHA, SSL_DHE_RSA_WITH_DES_CBC_SHA, SSL_DHE_DSS_WITH_DES_CBC_SHA, SSL_RSA_EXPORT_WITH_RC4_40_MD5, SSL_RSA_EXPORT_WITH_DES40_CBC_SHA, SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA, SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA, TLS_EMPTY_RENEGOTIATION_INFO_SCSV] 
Compression Methods: { 0 } 
*** 
%% Created: [Session-1, SSL_RSA_WITH_RC4_128_MD5] 
*** ServerHello, TLSv1 
RandomCookie: GMT: 1292088238 bytes = { 222,xxxxxx, 241 } 
Session ID: {77,xxxxxx, 235} 
Cipher Suite: SSL_RSA_WITH_RC4_128_MD5 
Compression Method: 0 
Extension renegotiation_info, renegotiated_connection: <empty> 
*** 
Cipher suite: SSL_RSA_WITH_RC4_128_MD5 
*** Certificate chain 
chain [0] = [ 
[ 
    Version: V3 
    Subject: CN=xxxxxx Server, OU=communication, O=xxxxxx, L=Zuerich, ST=ZH, C=CH 
    Signature Algorithm: SHA1withRSA, OID = 1.2.840.113549.1.1.5 

    Key: Sun RSA public key, 1024 bits 
    modulus: 948772xxxxxx17628447913191 
    public exponent: 65537 
    Validity: [From: Thu Dec 09 17:04:05 CET 2010, 
       To: Wed Jul 03 18:04:05 CEST 2109] 
    Issuer: CN=xxxxxx Server, OU=communication, O=xxxxxx, L=Zuerich, ST=ZH, C=CH 
    SerialNumber: [ 4d00fdf5] 

] 
    Algorithm: [SHA1withRSA] 
    Signature: 
0000: 6F 06 1D EA E9 DC 5B 5D EC EB 33 D4 47 01 94 1A o.....[]..3.G... 
xxxxxx 
0070: 99 78 C4 31 5F 84 8F 7B C1 2F 10 A1 9F 50 72 A1 .x.1_..../...Pr. 

] 
*** 
*** CertificateRequest 
Cert Types: RSA, DSS 
Cert Authorities: 
<CN=xxxxxx Client, OU=communication, O=xxxxxx, L=Zuerich, ST=ZH, C=CH> 
*** ServerHelloDone 
[write] MD5 and SHA1 hashes: len = 897 
0000: 02 00 00 4D 03 01 4D 04 B4 AE DE E4 AF 62 FA 48 ...M..M......b.H 
0xxxxxx 
0380: 00             . 
main, WRITE: TLSv1 Handshake, length = 897 
main, READ: TLSv1 Handshake, length = 141 
*** Certificate chain 
*** 
main, SEND TLSv1 ALERT: fatal, description = bad_certificate 
main, WRITE: TLSv1 Alert, length = 2 
main, called closeSocket() 
main, handling exception: javax.net.ssl.SSLHandshakeException: null cert chain 
main, IOException in getSession(): javax.net.ssl.SSLHandshakeException: null cert chain 
javax.net.ssl.SSLPeerUnverifiedException: peer not authenticated 
    at com.sun.net.ssl.internal.ssl.SSLSessionImpl.getPeerCertificateChain(Unknown Source) 
    at sslsocket.Server.getClientDistinguishedName(Server.java:86) 
    at sslsocket.Server.main(Server.java:37) 
+0

¿Qué sucede si agrega el certificado autofirmado del cliente a su propio almacén de confianza? –

+0

No hace ninguna diferencia. Todavía recibo el mismo error. – Chris

+0

Funciona para mí si mi almacén de confianza del servidor contiene el certificado del cliente y mi almacén de confianza del cliente contiene el certificado del servidor. –

Respuesta

14

La primera traza SSL parece ser parte de la segunda, muestra en el servidor. Por favor confirmar.

El segundo rastreo muestra que el servidor solicitó un certificado RSA o DSS firmado por 'CN = xxxxxx Cliente, OU = comunicación, O = xxxxxx, L = Zuerich, ST = ZH, C = CH', y el cliente respondió enviando una cadena de certificados vacía. Eso solo puede significar que el almacén de claves del cliente no tiene dicho certificado o que el cliente no estaba usando el almacén de claves correcto.

+0

Gracias por esa respuesta. Volví a revisar el almacén de claves de los clientes, aunque pensé que ya lo había hecho 100 veces. De todos modos, noté que el almacén de claves solo contenía la clave pública y no la clave privada del certificado del cliente. De alguna manera debo haberlo ensuciado. – Chris

+0

Esto fue útil, aclaró que o bien el certificado firmado CA o la clave privada o el almacén de claves completo debe faltar para que este proceso falle en este punto '*** Cadena de certificados' ... Para mí, el problema era que' SSLSocketFactory.getSocketFactory() 'carga automáticamente el almacén de confianza establecido por' -Djavax.net.ssl.trustStore' pero NO carga automáticamente el almacén de claves establecido por '-Djavax.net.ssl.keyStore' !! Así que tuve que hacer esto explícitamente: http://www.smartjava.org/content/client-certificates-httpclient-4 – pulkitsinghal

+2

Solo el SSLContext predeterminado obedece a javax.ney.ssl.keyStore. Los que construyes tú mismo con getInstance() no son por alguna razón. – EJP

Cuestiones relacionadas