170 votes

Réception d'une alerte fatale : handshake_failure par SSLHandshakeException

J'ai un problème avec la connexion SSL autorisée. J'ai créé une action Struts qui se connecte à un serveur externe avec un certificat SSL autorisé par le client. Dans mon action, j'essaie d'envoyer des données au serveur de la banque, mais sans succès, car j'ai comme résultat de la part du serveur l'erreur suivante :

error: javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure

Ma méthode de ma classe Action qui envoie des données au serveur

//Getting external IP from host
    URL whatismyip = new URL("http://automation.whatismyip.com/n09230945.asp");
    BufferedReader inIP = new BufferedReader(new InputStreamReader(whatismyip.openStream()));

    String IPStr = inIP.readLine(); //IP as a String

    Merchant merchant;

    System.out.println("amount: " + amount + ", currency: " + currency + ", clientIp: " + IPStr + ", description: " + description);

    try {

        merchant = new Merchant(context.getRealPath("/") + "merchant.properties");

    } catch (ConfigurationException e) {

        Logger.getLogger(HomeAction.class.getName()).log(Level.INFO, "message", e);
        System.err.println("error: " + e.getMessage());
        return ERROR;
    }

    String result = merchant.sendTransData(amount, currency, IPStr, description);

    System.out.println("result: " + result);

    return SUCCESS;

Mon fichier merchant.properties :

bank.server.url=https://-servernameandport-/
https.cipher=-cipher-

keystore.file=-key-.jks
keystore.type=JKS
keystore.password=-password-
ecomm.server.version=2.0

encoding.source=UTF-8
encoding.native=UTF-8

Pour la première fois, j'ai pensé qu'il s'agissait d'un problème de certificat, j'ai converti le fichier .pfx en .jks, mais j'ai la même erreur, sans aucun changement.

7voto

molly gu Points 56

Dans mon cas, le certificat est importé, mais l'erreur persiste ; j'ai résolu le problème en ajoutant les éléments suivants System.setProperty("https.protocols", "TLSv1.2,TLSv1.1,SSLv3"); avant la connexion

5voto

heez Points 735

En supposant que vous utilisiez les protocoles SSL/TLS appropriés, que vous configuriez correctement vos keyStore y trustStore et confirmé qu'il n'y a pas de problème avec les certificats eux-mêmes, il se peut que vous deviez renforcer vos algorithmes de sécurité .

Comme indiqué dans Réponse de Vineet L'une des raisons pour lesquelles vous recevez cette erreur est l'utilisation de suites de chiffrement incompatibles. En mettant à jour mon local_policy y US_export_policy dans le répertoire de mon JDK security avec ceux fournis dans le dossier Extension cryptographique Java (JCE) J'ai pu terminer la poignée de main avec succès.

4voto

Rich Points 1870

J'ai trouvé un serveur HTTPS qui échouait de cette manière si mon processus client Java était configuré avec

-Djsse.enableSNIExtension=false

La connexion a échoué avec handshake_failure après la ServerHello s'est terminé avec succès, mais avant que le flux de données ne démarre.

Il n'y avait pas de message d'erreur clair identifiant le problème, l'erreur se présentait simplement comme suit

main, READ: TLSv1.2 Alert, length = 2
main, RECV TLSv1.2 ALERT:  fatal, handshake_failure
%% Invalidated:  [Session-3, TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384]
main, called closeSocket()
main, handling exception: javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure

J'ai isolé le problème en essayant avec et sans la mention " -Djsse.enableSNIExtension=false option "

3voto

Armstrongya Points 1

J'ai rencontré le même problème aujourd'hui avec le client OkHttp pour GET une url basée sur https. C'était causé par un décalage entre la version du protocole Https et la méthode de chiffrement entre le serveur et le client. .

1) vérifiez la version du protocole https et la méthode de chiffrement de votre site web.

openssl>s_client -connect your_website.com:443 -showcerts

Vous obtiendrez de nombreuses informations détaillées, dont les principales sont les suivantes :

SSL-Session:
    Protocol  : TLSv1
    Cipher    : RC4-SHA

2) configurez votre client http, par exemple, dans Client OkHttp cas :

@Test()
public void testHttpsByOkHttp() {
    ConnectionSpec spec = new ConnectionSpec.Builder(ConnectionSpec.MODERN_TLS)
            .tlsVersions(TlsVersion.TLS_1_0) //protocol version
            .cipherSuites(
                    CipherSuite.TLS_RSA_WITH_RC4_128_SHA, //cipher method
                    CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
                    CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
                    CipherSuite.TLS_DHE_RSA_WITH_AES_128_GCM_SHA256)
            .build();

    OkHttpClient client = new OkHttpClient();
    client.setConnectionSpecs(Collections.singletonList(spec));
    Request request = new Request.Builder().url("https://your_website.com/").build();
    try {
        Response response = client.newCall(request).execute();
        if(response.isSuccessful()){
            logger.debug("result= {}", response.body().string());
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
}

Cela nous permettra d'obtenir ce que nous voulons.

2voto

user1483903 Points 35

J'utilise le client http de com.google.api. Lorsque je communique avec un site interne de l'entreprise, j'ai rencontré ce problème en utilisant par erreur https au lieu de http.

main, READ: TLSv1.2 Alert, length = 2
main, RECV TLSv1.2 ALERT:  fatal, handshake_failure
main, called closeSocket()
main, handling exception: javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure
main, IOException in getSession():  javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure
main, called close()
main, called closeInternal(true)
262 [main] DEBUG org.apache.http.impl.conn.DefaultClientConnection  - Connection shut down
main, called close()
main, called closeInternal(true)
263 [main] DEBUG org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager  - Released connection is not reusable.
263 [main] DEBUG org.apache.http.impl.conn.tsccm.ConnPoolByRoute  - Releasing connection [HttpRoute[{s}->https://<I-replaced>]][null]
263 [main] DEBUG org.apache.http.impl.conn.tsccm.ConnPoolByRoute  - Notifying no-one, there are no waiting threads
Exception in thread "main" javax.net.ssl.SSLPeerUnverifiedException: peer not authenticated
    at sun.security.ssl.SSLSessionImpl.getPeerCertificates(SSLSessionImpl.java:431)
    at org.apache.http.conn.ssl.AbstractVerifier.verify(AbstractVerifier.java:128)
    at org.apache.http.conn.ssl.SSLSocketFactory.connectSocket(SSLSocketFactory.java:339)
    at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:123)
    at org.apache.http.impl.conn.AbstractPoolEntry.open(AbstractPoolEntry.java:147)
    at org.apache.http.impl.conn.AbstractPooledConnAdapter.open(AbstractPooledConnAdapter.java:108)
    at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:415)
    at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:641)
    at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:576)
    at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:554)
    at com.google.api.client.http.apache.ApacheHttpRequest.execute(ApacheHttpRequest.java:67)
    at com.google.api.client.http.HttpRequest.execute(HttpRequest.java:960)

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X