2017-01-27 1 views
1

J'ai codé un client de service Web JAX-WS java. Lorsque je tente de frapper un serveur en utilisant un certificat CA public signé, je reçois une exception Handshake SSL:Certificat CA racine Java présent - obtention de l'exception SSL Handshake

com.sun.xml.internal.ws.client.ClientTransportException: HTTP transport error: javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target

J'ai étudié plus loin et avoir tourné sur le réseau de la machine virtuelle Java traçage et découvert que de l'émetteur du serveur certificat public signé est:

Issuer: CN=Symantec Class 3 Secure Server SHA256 SSL CA, OU=Symantec Trust Network, O=Symantec Corporation, C=US

J'ai vérifié que le certificat de CA racine pour cet émetteur est:

CN=VeriSign Universal Root Certification Authority, OU="(c) 2008 VeriSign, Inc. - For authorized use only", OU=VeriSign Trust Network, O="VeriSign, Inc.", C=US

Et j'ai vérifié par journal trace que ce certificat est en effet chargé.

Voici une partie de la trace d'enregistrement SSL:

keyStore is : 
keyStore type is : jks 
keyStore provider is : 

init keystore 
init keymanager of type SunX509 
trustStore is: C:\Program Files\Java\jdk1.7.0_79\jre\lib\security\cacerts 
trustStore type is : jks 
trustStore provider is : 
init truststore 

[ omitted] 

     adding as trusted cert: 
     Subject: CN=VeriSign Universal Root Certification Authority, OU="(c) 2008 VeriSign 
, Inc. - For authorized use only", OU=VeriSign Trust Network, O="VeriSign, Inc.", C=US 
     Issuer: CN=VeriSign Universal Root Certification Authority, OU="(c) 2008 VeriSign 
, Inc. - For authorized use only", OU=VeriSign Trust Network, O="VeriSign, Inc.", C=US 
     Algorithm: RSA; Serial number: 0x401ac46421b30ebbe4121ac51d 
     Valid from Tue Apr 01 17:00:00 PDT 2008 until Tue Dec 01 15:59:59 PST 2037 
[ omitted] 

trigger seeding of SecureRandom 
done seeding SecureRandom 
Ignoring unavailable cipher suite: TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA 
Ignoring unavailable cipher suite: TLS_DHE_RSA_WITH_AES_256_CBC_SHA 
Ignoring unavailable cipher suite: TLS_ECDH_RSA_WITH_AES_256_CBC_SHA 
Ignoring unsupported cipher suite: TLS_DHE_DSS_WITH_AES_128_CBC_SHA256 
Ignoring unsupported cipher suite: TLS_DHE_DSS_WITH_AES_256_CBC_SHA256 
Ignoring unsupported cipher suite: TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 
Ignoring unsupported cipher suite: TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256 
Ignoring unsupported cipher suite: TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 
Ignoring unsupported cipher suite: TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 
Ignoring unsupported cipher suite: TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384 
Ignoring unsupported cipher suite: TLS_RSA_WITH_AES_256_CBC_SHA256 
Ignoring unavailable cipher suite: TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA 
Ignoring unsupported cipher suite: TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 
Ignoring unsupported cipher suite: TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 
Ignoring unavailable cipher suite: TLS_DHE_DSS_WITH_AES_256_CBC_SHA 
Ignoring unsupported cipher suite: TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384 
Ignoring unsupported cipher suite: TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 
Ignoring unsupported cipher suite: TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256 
Ignoring unavailable cipher suite: TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA 
Ignoring unavailable cipher suite: TLS_RSA_WITH_AES_256_CBC_SHA 
Ignoring unsupported cipher suite: TLS_RSA_WITH_AES_128_CBC_SHA256 
Allow unsafe renegotiation: false 
Allow legacy hello messages: true 
Is initial handshake: true 
Is secure renegotiation: false 
main, setSoTimeout(0) called 
%% No cached client session 
*** ClientHello, TLSv1 
RandomCookie: GMT: 1468680588 bytes = 
Session ID: {} 
Cipher Suites: [ ... ] 
Compression Methods: { 0 } 
Extension elliptic_curves, curve names: 
Extension ec_point_formats, formats: [uncompressed] 
Extension server_name, server_name: [host_name: redacted] 
*** 
[write] MD5 and SHA1 hashes: len = 181 

[omitted] 

*** ServerHello, TLSv1 
RandomCookie: GMT: 1524806833 
Session ID: 
Cipher Suite: TLS_DHE_RSA_WITH_AES_128_CBC_SHA 
Compression Method: 0 
Extension renegotiation_info, renegotiated_connection: <empty> 
Extension server_name, server_name: 
*** 
%% Initialized: [Session-1, TLS_DHE_RSA_WITH_AES_128_CBC_SHA] 
** TLS_DHE_RSA_WITH_AES_128_CBC_SHA 
[read] MD5 and SHA1 hashes: len = 85 

[omitted] 

*** Certificate chain 
chain [0] = [ 
[ 
    Version: V3 
    Subject: CN=redacted, OU=redacted, O=redacted, L=redacted, ST=redacted, C=US 
    Signature Algorithm: SHA256withRSA, OID = 1.2.840.113549.1.1.11 

    Key: Sun RSA public key, 2048 bits 
    modulus: 
    public exponent: 65537 
    Validity: [From: Sun Oct 16 17:00:00 PDT 2016, 
       To: Thu Nov 02 16:59:59 PDT 2017] 
    Issuer: CN=Symantec Class 3 Secure Server SHA256 SSL CA, 
      OU=Symantec Trust Network, O=Symantec Corporation, C=US 
    SerialNumber: [ ... ] 

Certificate Extensions: 9 
[1]: ObjectId: 1.3.6.1.4.1.11129.2.4.2 Criticality=false 
Extension unknown: DER encoded OCTET string = 

[omitted] 

*** 
%% Invalidated: [Session-1, TLS_DHE_RSA_WITH_AES_128_CBC_SHA] 
main, SEND TLSv1 ALERT: fatal, description = certificate_unknown 
main, WRITE: TLSv1 Alert, length = 2 
[Raw write]: length = 7 
0000: 15 03 01 00 02 02 2E        ....... 
main, called closeSocket() 
main, handling exception: javax.net.ssl.SSLHandshakeException: 

Quelqu'un at-il des suggestions quant à ce qui pourrait être la cause de ce problème?

Répondre

1

unable to find valid certification path to requested target signifie que le client ne soit pas faire confiance au certificat de serveur en raison de

  1. chaîne incomplète du certificat feuille à la racine ou
  2. certificat racine n'est pas présent en truststore

J'ai vérifié que Symantec Class 3 Secure Server SHA256 SSL CA est émis par VeriSign Universal Root Certification Authority (voir Symantec page)

Symantec & Verisign

Et Verisign racine est effectivement inclus dans jdk1.7.0_79, donc je gaspille 2). Par conséquent, ma supposition est une chaîne incomplète du côté serveur.

Actions

  1. serveur Vérifiez à la recherche d'https://www.ssllabs.com 'erreurs de chaîne incomplètes'.

  2. Vérifiez que l'autorité de certification intermédiaire est vraiment Symantec Class 3 Secure Server SHA256 SSL CA avec le numéro de série 69 87 94 19 d9 e3 62 70 74 9d bb e5 9d c6 68 5e

  3. En cas d'erreur à l'étape 1, téléchargez Symantec cert (de lien ci-dessus) et importer dans votre truststore

  4. Si le certificat intermédiaire est pas prévu de Symantec, puis obtenir l'autorité de certification racine et l'importer dans votre trustore

Vérification de confiance SSL EDITED

Les certificats sont émis dans une hiérarchie. Chaque certificat est signé par l'émetteur du niveau supérieur, de l'autorité de certification racine aux certificats feuille. La signature numérique permet de vérifier la chaîne de certification.

Le serveur SSL doit fournir le certificat et la chaîne (sans la racine). Le gestionnaire de confiance vérifie la chaîne de certification de feuille à racine. Si quelqu'un des certificats se trouve dans le truststore le certificat est alors « de confiance » (même si elle est expiré ...)

Vous devez inclure l'autorité de certification racine dans le truststore, et non pas la feuille

+0

Alors laissez-moi Comprenez cela un peu mieux. Si votre magasin de confiance manque des certificats dans la chaîne, le certificat du serveur ne peut pas être vérifié car il ne peut pas trouver le chemin. Je suppose, puisqu'il s'agit d'une chaîne, et parce que l'autorité de certification ROOT est présente, le leaf OU le certificat intermédiaire aurait une sorte de référence au certificat d'autorité de certification racine. Sinon, quel est le but d'avoir un certificat ROOT? Le certificat CA racine ne devrait-il pas être la vérification ultime? Sinon, pourquoi les certs intermédiaires et les cercles de feuilles ne contiennent-ils pas les références de la chaîne en elle-même? – Matt1776

+0

Je vous aurais accordé la prime parce que vous avez fourni une réponse plus complète - mais Magnus a également répondu et résolu mon problème et y est arrivé en premier. Aussi, il a moins de rep. Merci d'avoir pris le temps de le faire, vous m'avez montré d'autres outils et moyens de vérification. J'apprécie cela. – Matt1776

+1

J'ai inclus dans la réponse une explication sur le fonctionnement de la vérification de confiance – pedrofb

2

L'arbre de confiance ressemble

root-> VeriSign Universal Root Certification Authority 
chain-> Symantec Class 3 Secure Server SHA256 SSL CA 
leaf-> somewebsite 

Vous pouvez avoir plusieurs chaînes ou pas de chaînes. Les navigateurs ont tendance à inclure les certificats racine ainsi que les certificats de chaîne populaires dans leurs magasins de confiance.

Mais il semble que le magasin de confiance java ne possède pas ce certificat de chaîne particulier.
En tant que tel lorsque vous essayez de vous connecter, java n'a aucun moyen de savoir que le certificat racine est finalement approuvé par le certificat racine car il ne le trouve pas, il ne peut pas trouver un chemin.
Il y a deux façons de traiter cela, idéalement l'opérateur du serveur configurerait leur serveur pour présenter la chaîne de certificats, si cela n'est pas possible, vous pouvez simplement importer manuellement le certificat de chaîne dans javas trust store.

Download the cert
l'importer

keytool -import -file Example.cer -keystore examplekeystore