17
votes

SSLHandshakeException avec le runtime créé par jlink

J'ai une application dropwizard, qui fonctionne bien avec le JRE standard.

J'ai essayé de créer un runtime en utilisant jlink qui est considérablement plus petit:

redis_1  | 09:12:20 stunnel.1 | 2019.03.31 09:12:20 LOG7[23]: TLS alert (write): fatal: handshake failure
redis_1  | 09:12:20 stunnel.1 | 2019.03.31 09:12:20 LOG3[23]: SSL_accept: 141F7065: error:141F7065:SSL routines:final_key_share:no suitable key share
redis_1  | 09:12:20 stunnel.1 | 2019.03.31 09:12:20 LOG5[23]: Connection reset: 0 byte(s) sent to TLS, 0 byte(s) sent to socket

Si je l'exécute avec le runtime créé par jlink, il jette cette erreur de connexion à redis (qui a stunnel devant lui).

ERROR [2019-03-31 09:12:20,080] com.company.project.core.WorkerThread: Failed to process message.
! javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure
! at java.base/sun.security.ssl.Alert.createSSLException(Unknown Source)
! at java.base/sun.security.ssl.Alert.createSSLException(Unknown Source)
! at java.base/sun.security.ssl.TransportContext.fatal(Unknown Source)
! at java.base/sun.security.ssl.Alert$AlertConsumer.consume(Unknown Source)
! at java.base/sun.security.ssl.TransportContext.dispatch(Unknown Source)
! at java.base/sun.security.ssl.SSLTransport.decode(Unknown Source)
! at java.base/sun.security.ssl.SSLSocketImpl.decode(Unknown Source)
! at java.base/sun.security.ssl.SSLSocketImpl.readHandshakeRecord(Unknown Source)
! at java.base/sun.security.ssl.SSLSocketImpl.startHandshake(Unknown Source)
! at java.base/sun.security.ssl.SSLSocketImpl.ensureNegotiated(Unknown Source)
! at java.base/sun.security.ssl.SSLSocketImpl$AppOutputStream.write(Unknown Source)
! at redis.clients.jedis.util.RedisOutputStream.flushBuffer(RedisOutputStream.java:52)
! at redis.clients.jedis.util.RedisOutputStream.flush(RedisOutputStream.java:133)
! at redis.clients.jedis.Connection.flush(Connection.java:300)
! ... 9 common frames omitted
! Causing: redis.clients.jedis.exceptions.JedisConnectionException: javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure
! at redis.clients.jedis.Connection.flush(Connection.java:303)
! at redis.clients.jedis.Connection.getStatusCodeReply(Connection.java:235)
! at redis.clients.jedis.BinaryJedis.auth(BinaryJedis.java:2225)
! at redis.clients.jedis.JedisFactory.makeObject(JedisFactory.java:119)
! at org.apache.commons.pool2.impl.GenericObjectPool.create(GenericObjectPool.java:888)
! at org.apache.commons.pool2.impl.GenericObjectPool.borrowObject(GenericObjectPool.java:432)
! at org.apache.commons.pool2.impl.GenericObjectPool.borrowObject(GenericObjectPool.java:361)
! at redis.clients.jedis.util.Pool.getResource(Pool.java:50)
! ... 2 common frames omitted
! Causing: redis.clients.jedis.exceptions.JedisConnectionException: Could not get a resource from the pool
! at redis.clients.jedis.util.Pool.getResource(Pool.java:59)
! at redis.clients.jedis.JedisPool.getResource(JedisPool.java:234)

Les journaux du serveur stunnel montrent:

/Library/Java/JavaVirtualMachines/jdk-11.jdk/Contents/Home/bin/jlink --no-header-files --no-man-pages --compress=2 --strip-debug --add-modules java.base,java.compiler,java.desktop,java.instrument,java.logging,java.management,java.naming,java.scripting,java.security.jgss,java.sql,java.xml,jdk.attach,jdk.jdi,jdk.management,jdk.unsupported --output jre

Y a-t-il des algorithmes de cryptage laissés de côté par jlink?


2 commentaires

Hmmn. Si j'ajoute jdk.crypto.ec cela fonctionne - pourquoi jdeps aurait-il omis celui-là, si celui-là, y en aurait-il d'autres?


Je semble rappeler que les fournisseurs JCA sont des extensions: rien dans la bibliothèque ne dépend directement d'eux, ils doivent être mis explicitement dans le classpath (comme d'autres extensions d'adaptateur typiques: connecteurs de base de données, etc.)


4 Réponses :


25
votes

Comme le mentionne rich dans un commentaire

Hmmn. Si j'ajoute jdk.crypto.ec cela fonctionne - pourquoi jdeps aurait-il omis celui-là, si celui-là, y en aurait-il d'autres?

l'ajout de jdk.crypto.ec à la liste des modules a résolu le problème.


3 commentaires

Vous pouvez donc relier un runtime parfaitement bon avec le support HTTPS, mais sans implémentation SSL / TLS / ... et ne remarquer que lorsque la poignée de main échoue avec un message d'erreur qui est ... obscurcissant. Je comprends pourquoi cela se produit, mais ce n'est certainement pas pratique ni suivre le principe de la moindre surprise.


C'est extrêmement frustrant, c'était la solution. J'ai déployé mon application pendant des mois sur un JRE, puis j'ai soudainement perdu la capacité de parler à mon serveur (ce qui signifie aucune mise à jour). Pourquoi n'incluraient-ils pas simplement cela?


Sur OpenJDK11.0.9 / Win64, cela augmente la taille du JRE de 0.3 MiB



4
votes

On pourrait aussi simplement ajouter --bind-services (lien dans les modules du fournisseur de services et leurs dépendances) à la commande jlink. Mais d'après mon expérience, cela rendra le temps d'exécution beaucoup plus important. Mais au moins, c'est une option pour savoir rapidement si les problèmes observés sont dus à une implémentation de service manquante.


0 commentaires

3
votes

Ajouté requires jdk.crypto.ec; dans module-info.java a corrigé le problème pour moi.


0 commentaires

0
votes

J'ai également dû ajouter jdk.crypto.ec et jdk.crypto.cryptoki .


0 commentaires