2017-07-17 2 views
1

Je travaille dans java1.8 et je me connecte à APNS (api.push.apple.com) via OKHTTP. Le symptôme est une prise de contact SSL défaillante: javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure, qui selon mes recherches indique que le serveur n'a pas pu négocier un chiffrement avec le client.Java 1.8: TLSv1.2 Échec du handshake ClientHello (extensions de courbe elliptique manquantes?)

Le code crée simplement un contexte SSL via SSLContext.getInstance("TLS").

Après avoir exécuté ma demande avec -Djavax.net.debug=all, je trouve que la ma poignée de main SSL ClientHello ressemble à ceci:

*** ClientHello, TLSv1.2 
RandomCookie: GMT: 1500317763 bytes = { 59, 94, 246, 29, 243, 123, 94, 45, 2, 86, 47, 12, 198, 219, 164, 71, 166, 30, 143, 25, 190, 34, 243, 50, 24, 239, 0, 131 } 
Session ID: {} 
Cipher Suites: [TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, TLS_DHE_RSA_WITH_AES_128_GCM_SHA256, TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_RSA_WITH_AES_128_CBC_SHA, TLS_RSA_WITH_AES_128_GCM_SHA256, TLS_RSA_WITH_AES_128_CBC_SHA, SSL_RSA_WITH_3DES_EDE_CBC_SHA] 
Compression Methods: { 0 } 
Extension signature_algorithms, signature_algorithms: SHA512withECDSA, SHA512withRSA, SHA384withECDSA, SHA384withRSA, SHA256withECDSA, SHA256withRSA, SHA256withDSA, SHA224withECDSA, SHA224withRSA, SHA224withDSA, SHA1withECDSA, SHA1withRSA, SHA1withDSA 
Extension server_name, server_name: [type=host_name (0), value=api.push.apple.com] 
Extension renegotiation_info, renegotiated_connection: <empty> 
Extension application_layer_protocol_negotiation, protocols: [h2, spdy/3.1, http/1.1] 
*** 

qui est fondamentalement juste suivi avec un

OkHttp https://api.push.apple.com/3/device/token, READ: TLSv1.2 Alert, length = 2 
OkHttp https://api.push.apple.com/3/device/token, RECV TLSv1.2 ALERT: fatal, handshake_failure 

déroutants chose est que le code fonctionne avec succès sur l'ordinateur portable d'un collègue - le SSL ClientHello est identique, sauf qu'il comprend deux entrées suivantes:

Extension elliptic_curves, curve names: {secp256r1, sect163k1, sect163r2, secp192r1, secp224r1, sect233k1, sect233r1, sect283k1, sect283r1, secp384r1, sect409k1, sect409r1, secp521r1, sect571k1, sect571r1, secp160k1, secp160r1, secp160r2, sect163r1, secp192k1, sect193r1, sect193r2, secp224k1, sect239k1, secp256k1} 
Extension ec_point_formats, formats: [uncompressed] 

Analyse SSL pour le serveur APNS (https://www.ssllabs.com/ssltest/analyze.html?d=api.push.apple.com&s=17.188.154.31) montre qu'il accepte uniquement TLSv1.2 et les chiffrements suivants:

TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 (0xcca8) ECDH secp256r1 (eq. 3072 bits RSA) FS 256 
TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (0xc030) ECDH secp256r1 (eq. 3072 bits RSA) FS 256 
TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (0xc02f) ECDH secp256r1 (eq. 3072 bits RSA) FS 128 

qui me fait penser que les disparus Extension s dans le SSL la poignée de main fait que le serveur rejette ma poignée de main sur la base de l'absence de code commun à utiliser.


Le portable sur lequel il s'exécute est OS X 10.10, alors que celui dans lequel il est cassé est macOS 10.12. Nous sommes tous les deux sur Java1.8.


Si quelqu'un a des pistes sur ce sujet, il serait grandement apprécié.

Merci pour votre temps.

Répondre

2

Probablement les absents extensions CE sont ce qui cause le problème, bien que techniquement il est permis - voir RFC 4492 section 4:

Un client qui propose des suites de chiffrement ECC peuvent choisir de ne pas inclure ces extensions. Dans ce cas, le serveur est libre de choisir une des courbes elliptiques ou des formats de points énumérés à la section 5.

qui peut encore aller mal, mais sans doute pas avant de recevoir le premier vol (ServerHello du serveur. .. ServerHelloDone), donc je suppose que le serveur ne permet pas cette absence.

Je pense qu'il est assez étrange pour JDK8 de ne pas envoyer cette extension, donc je m'attends à ce que votre JDK soit étrangement configuré et qu'il soit préférable d'installer et de tester un tout nouveau JDK8 (non modifié). JCE Unlimited Strength "fichiers de stratégie).

J'ai brièvement regardé le (OpenJDK) la source JDK8, et il y a deux possibilités pour expliquer pourquoi cette extension pourrait être absent:

  • D'une certaine façon le fournisseur cryptographique JCE pour « CE » est manquant ou n » t supporte les courbes TLS. Examinez votre liste jre/lib/security/java.security des entrées security.provider et toutes les modifications de fournisseur programmatique que vous effectuez. Essayez-vous d'utiliser une sorte de jeton matériel pour l'authentification du client?
  • Vous avez peut-être la propriété système "jdk.tls.namedGroups" (si elle était vide, vous devriez voir une exception, mais vous avez peut-être listé uniquement des courbes non supportées). Vérifiez les autres propriétés du système que vous avez définies.

Selon le code source, il peut être une ligne dans votre journal de débogage généré par l'impossibilité de trouver des courbes:

 if (debug != null && idList.isEmpty()) { 
     debug.println(
      "Initialized [jdk.tls.namedGroups|default] list contains " + 
      "no available elliptic curves. " + 
      (property != null ? "(" + property + ")" : "[Default]")); 
    } 

S'il vous plaît indiquer si vous voyez ce message, et ce qu'il dit. Il peut également être utile de connaître la version exacte de JDK8 que vous utilisez et si le mode FIPS est activé.