Obtener SSLHandshakeException cuando se usa Dropbox Java SDK para API v2
En un XPages aplicación Quiero hacer uso de laDropbox Java SDK (2.1.2) para API v2 para obtener información sobre mi cuenta de Dropbox. El siguiente código se utiliza para recuperar el objeto de cuenta correspondiente:
String atoken = "****";
DbxRequestConfig rc = new DbxRequestConfig("****");
DbxClientV2 client = new DbxClientV2(rc,atoken);
DbxUserUsersRequests users = client.users();
FullAccount acc = users.getCurrentAccount(); // Exception raised here
La última línea plantea la siguiente excepción:
com.dropbox.core.NetworkIOException: No appropriate protocol
at com.dropbox.core.DbxRequestUtil.startPostRaw(DbxRequestUtil.java:240)
...
Caused by: javax.net.ssl.SSLHandshakeException: No appropriate protocol
at com.ibm.jsse2.kb.c(kb.java:347)
...
Del stacktrace llegué a la conclusión de que IBMJSSE2 es el proveedor de seguridad utilizado para manejar el protocolo de enlace SSL. Así que ejecuté el código desde arriba en una JVM que no es Domino (JRE7) que usa la SunJSSE proveedor de seguridad y funcionó sin ningún problema. Por lo tanto, el problema debe estar relacionado con la JVM Domino de IBM, pero no puedo encontrar la manera de solucionarlo.
Puede alguien ayudarme con esto o dar una pista para una solución?
Información Adiciona:
Versión del servidor Domino: 9.0.1 FP4 HF70
Java versión de tiempo de ejecución: pwa6460sr16fp4-20150414_01 (SR16 FP4) [22B8: 0002-1E88]
ersión @JVM:JRE 1.6.0 IBM J9 2.4 Windows 7 amd64-64 jvmwa6460sr16fp4-20150406_242976 (JIT habilitado, AOT habilitado) J9VM - 20150406_242976 JIT - r9_20150402_88984 GC - GA24_Java6_SR16_20150406_1410_B242976
e han instalado archivos de políticas JCE sin restricciones en Domino JVM.
Propiedades de la IBMJSSE2 proveedor de seguridad:
Alg.Alias.TrustManagerFactory.IbmPKIX = PKIX
Alg.Alias.TrustManagerFactory.X.509 = PKIX
Alg.Alias.TrustManagerFactory.X509 = PKIX
KeyManagerFactory.IbmX509 = com.ibm.jsse2.rc$a_
KeyManagerFactory.NewIbmX509 = com.ibm.jsse2.rc$b_
Provider.id className = com.ibm.jsse2.IBMJSSEProvider2
Provider.id info = IBM JSSE provider2 (implements IbmX509 key/trust factories, SSLv3, TLSv1)
Provider.id name = IBMJSSE2
Provider.id version = 1.6
SSLContext.Default = com.ibm.jsse2.tc
SSLContext.SSL = com.ibm.jsse2.uc
SSLContext.SSL_TLS = com.ibm.jsse2.vc
SSLContext.SSL_TLSv2 = com.ibm.jsse2.wc
SSLContext.TLS = com.ibm.jsse2.yc
SSLContext.TLSv1 = com.ibm.jsse2.zc
SSLContext.TLSv1.1 = com.ibm.jsse2.ad
SSLContext.TLSv1.2 = com.ibm.jsse2.bd
TrustManagerFactory.IbmX509 = com.ibm.jsse2.ed$b_
TrustManagerFactory.PKIX = com.ibm.jsse2.ed$a_
Rastreo completo de excepciones:
com.dropbox.core.NetworkIOException: No appropriate protocol
at com.dropbox.core.DbxRequestUtil.startPostRaw(DbxRequestUtil.java:240)
at com.dropbox.core.v2.DbxRawClientV2$1.execute(DbxRawClientV2.java:100)
at com.dropbox.core.v2.DbxRawClientV2.executeRetriable(DbxRawClientV2.java:256)
at com.dropbox.core.v2.DbxRawClientV2.rpcStyle(DbxRawClientV2.java:97)
at com.dropbox.core.v2.users.DbxUserUsersRequests.getCurrentAccount(DbxUserUsersRequests.java:120)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:60)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:37)
at java.lang.reflect.Method.invoke(Method.java:611)
at com.ibm.jscript.types.JavaAccessObject.call(JavaAccessObject.java:321)
at com.ibm.jscript.types.FBSObject.call(FBSObject.java:161)
at com.ibm.jscript.ASTTree.ASTCall.interpret(ASTCall.java:197)
at com.ibm.jscript.ASTTree.ASTAssign.interpret(ASTAssign.java:91)
at com.ibm.jscript.ASTTree.ASTBlock.interpret(ASTBlock.java:100)
at com.ibm.jscript.ASTTree.ASTTry.interpret(ASTTry.java:109)
at com.ibm.jscript.ASTTree.ASTBlock.interpret(ASTBlock.java:100)
at com.ibm.jscript.ASTTree.ASTTry.interpret(ASTTry.java:109)
at com.ibm.jscript.std.FunctionObject._executeFunction(FunctionObject.java:261)
at com.ibm.jscript.std.FunctionObject.executeFunction(FunctionObject.java:185)
at com.ibm.jscript.std.FunctionObject.call(FunctionObject.java:171)
at com.ibm.jscript.types.FBSObject.call(FBSObject.java:161)
at com.ibm.jscript.ASTTree.ASTCall.interpret(ASTCall.java:197)
at com.ibm.jscript.ASTTree.ASTAssign.interpret(ASTAssign.java:91)
at com.ibm.jscript.ASTTree.ASTBlock.interpret(ASTBlock.java:100)
at com.ibm.jscript.ASTTree.ASTIf.interpret(ASTIf.java:85)
at com.ibm.jscript.ASTTree.ASTProgram.interpret(ASTProgram.java:119)
at com.ibm.jscript.types.FBSGlobalObject$GlobalMethod.call(FBSGlobalObject.java:280)
at com.ibm.jscript.types.FBSObject.call(FBSObject.java:161)
at com.ibm.jscript.types.FBSGlobalObject$GlobalMethod.call(FBSGlobalObject.java:219)
at com.ibm.jscript.ASTTree.ASTCall.interpret(ASTCall.java:197)
at com.ibm.jscript.ASTTree.ASTBlock.interpret(ASTBlock.java:100)
at com.ibm.jscript.ASTTree.ASTIf.interpret(ASTIf.java:85)
at com.ibm.jscript.ASTTree.ASTBlock.interpret(ASTBlock.java:100)
at com.ibm.jscript.ASTTree.ASTTry.interpret(ASTTry.java:109)
at com.ibm.jscript.std.FunctionObject._executeFunction(FunctionObject.java:261)
at com.ibm.jscript.std.FunctionObject.executeFunction(FunctionObject.java:185)
at com.ibm.jscript.std.FunctionObject.call(FunctionObject.java:171)
at com.ibm.jscript.std.FunctionPrototype$FunctionMethod.call(FunctionPrototype.java:169)
at com.ibm.jscript.types.FBSObject.call(FBSObject.java:161)
at com.ibm.jscript.ASTTree.ASTCall.interpret(ASTCall.java:197)
at com.ibm.jscript.ASTTree.ASTAssign.interpret(ASTAssign.java:91)
at com.ibm.jscript.ASTTree.ASTBlock.interpret(ASTBlock.java:100)
at com.ibm.jscript.ASTTree.ASTIf.interpret(ASTIf.java:85)
at com.ibm.jscript.ASTTree.ASTBlock.interpret(ASTBlock.java:100)
at com.ibm.jscript.ASTTree.ASTTry.interpret(ASTTry.java:109)
at com.ibm.jscript.ASTTree.ASTProgram.interpret(ASTProgram.java:119)
at com.ibm.jscript.ASTTree.ASTProgram.interpretEx(ASTProgram.java:139)
at com.ibm.jscript.JSExpression._interpretExpression(JSExpression.java:435)
at com.ibm.jscript.JSExpression.access$1(JSExpression.java:424)
at com.ibm.jscript.JSExpression$2.run(JSExpression.java:414)
at java.security.AccessController.doPrivileged(AccessController.java:448)
at com.ibm.jscript.JSExpression.interpretExpression(JSExpression.java:410)
at com.ibm.jscript.JSExpression.evaluateValue(JSExpression.java:251)
at com.ibm.jscript.JSExpression.evaluateValue(JSExpression.java:234)
at com.ibm.xsp.javascript.JavaScriptInterpreter.interpret(JavaScriptInterpreter.java:222)
at com.ibm.xsp.binding.javascript.JavaScriptMethodBinding.invoke(JavaScriptMethodBinding.java:111)
at com.ibm.xsp.component.UIViewRootEx.invokePhaseMethodBinding(UIViewRootEx.java:1735)
at com.ibm.xsp.controller.FacesControllerImpl.invokePhaseMethodBinding(FacesControllerImpl.java:450)
at com.ibm.xsp.controller.FacesControllerImpl.access$0(FacesControllerImpl.java:444)
at com.ibm.xsp.controller.FacesControllerImpl$ViewPhaseListener.afterPhase(FacesControllerImpl.java:512)
at com.sun.faces.lifecycle.LifecycleImpl.phase(LifecycleImpl.java:218)
at com.sun.faces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:120)
at com.ibm.xsp.controller.FacesControllerImpl.render(FacesControllerImpl.java:270)
at com.ibm.xsp.webapp.FacesServlet.serviceView(FacesServlet.java:261)
at com.ibm.xsp.webapp.FacesServletEx.serviceView(FacesServletEx.java:157)
at com.ibm.xsp.webapp.FacesServlet.service(FacesServlet.java:160)
at com.ibm.xsp.webapp.FacesServletEx.service(FacesServletEx.java:138)
at com.ibm.xsp.webapp.DesignerFacesServlet.service(DesignerFacesServlet.java:103)
at com.ibm.designer.runtime.domino.adapter.ComponentModule.invokeServlet(ComponentModule.java:576)
at com.ibm.domino.xsp.module.nsf.NSFComponentModule.invokeServlet(NSFComponentModule.java:1335)
at com.ibm.designer.runtime.domino.adapter.ComponentModule$AdapterInvoker.invokeServlet(ComponentModule.java:853)
at com.ibm.designer.runtime.domino.adapter.ComponentModule$ServletInvoker.doService(ComponentModule.java:796)
at com.ibm.designer.runtime.domino.adapter.ComponentModule.doService(ComponentModule.java:565)
at com.ibm.domino.xsp.module.nsf.NSFComponentModule.doService(NSFComponentModule.java:1319)
at com.ibm.domino.xsp.module.nsf.NSFService.doServiceInternal(NSFService.java:662)
at com.ibm.domino.xsp.module.nsf.NSFService.doService(NSFService.java:482)
at com.ibm.designer.runtime.domino.adapter.LCDEnvironment.doService(LCDEnvironment.java:357)
at com.ibm.designer.runtime.domino.adapter.LCDEnvironment.service(LCDEnvironment.java:313)
at com.ibm.domino.xsp.bridge.http.engine.XspCmdManager.service(XspCmdManager.java:272)
Caused by: javax.net.ssl.SSLHandshakeException: No appropriate protocol
at com.ibm.jsse2.kb.c(kb.java:347)
at com.ibm.jsse2.SSLSocketImpl.i(SSLSocketImpl.java:363)
at com.ibm.jsse2.SSLSocketImpl.h(SSLSocketImpl.java:650)
at com.ibm.jsse2.SSLSocketImpl.a(SSLSocketImpl.java:669)
at com.ibm.jsse2.SSLSocketImpl.startHandshake(SSLSocketImpl.java:95)
at com.ibm.net.ssl.www2.protocol.https.c.afterConnect(c.java:162)
at com.ibm.net.ssl.www2.protocol.https.d.connect(d.java:36)
at sun.net.www.protocol.http.HttpURLConnection.getOutputStream(HttpURLConnection.java:1044)
at com.ibm.net.ssl.www2.protocol.https.b.getOutputStream(b.java:53)
at com.dropbox.core.http.StandardHttpRequestor.getOutputStream(StandardHttpRequestor.java:123)
at com.dropbox.core.http.StandardHttpRequestor.access$000(StandardHttpRequestor.java:28)
at com.dropbox.core.http.StandardHttpRequestor$Uploader.(StandardHttpRequestor.java:133)
at com.dropbox.core.http.StandardHttpRequestor.startPost(StandardHttpRequestor.java:72)
at com.dropbox.core.http.StandardHttpRequestor.startPost(StandardHttpRequestor.java:28)
at com.dropbox.core.DbxRequestUtil.startPostRaw(DbxRequestUtil.java:232)
...
Actualiza: Después de configurarjavax.net.debug=ssl:handshake:data
(como lo sugiere Jigar Joshi), el registro de errores y el registro de seguimiento proporcionan la siguiente información adicional:
Certificado con asunto EMAILADDRESS = ****, CN = ****, O = ****, L = ****, ST = ****, C = ****, emitido por CN = ****, OU = ****, O = ****, C = ****, no es de confianza. La validación falló con el error 3659.
CommonBaseEventLogRecord:sourceClassName = com.ibm.domino.napi.ssl.DominoX509TrustManager
CommonBaseEventLogRecord:sourceMethodName = checkServerTrusted
<sourcecomponentid component="Expeditor 6.2" componentidtype="ProductName" instanceid="" location="****" locationtype="Hostname" subcomponent="com.ibm.domino.napi.ssl" threadid="5" componenttype="http://www.w3.org/2001/XMLSchema-instance">
El certificado en el que no se confía esmí, aunque todos los certificados y la clave privada se importaron a mi almacén de claves. El hecho de que el almacén de claves funcione en la JVM no Domino me permite concluir que el archivo del almacén de claves debe ser válido. Sin embargo, aún no se confía en el certificado cuando se ejecuta el código en Domino JVM.
Actualiza: La parte central de la salida de depuración javax.net.debug=ssl:handshake
) e
SSLContextImpl: Using X509ExtendedKeyManager com.ibm.jsse2.hd
SSLContextImpl: Using X509TrustManager com.ibm.jsse2.pc
IBMJSSE2 will ignore com.ibm.jsse2.overrideDefaultProtocol since was set to a non recognized value TLSv1
Installed Providers = IBMJSSE2, IBMJCE, IBMJGSSProvider, IBMCertPath, IBMSASL, IBMXMLCRYPTO, IBMXMLEnc, Policy, IBMSPNEGO
JsseJCE: Using SecureRandom IBMSecureRandom from provider IBMJCE version 1.2
trigger seeding of SecureRandom
done seeding SecureRandom
IBMJSSE2 will enable CBC protection
IBMJSSE2 to send SCSV Cipher Suite on initial ClientHello
JsseJCE: Using SecureRandom IBMSecureRandom from provider IBMJCE version 1.2
IBMJSSE2 will allow RFC 5746 renegotiation per com.ibm.jsse2.renegotiate set to none or default
IBMJSSE2 will not require renegotiation indicator during initial handshake per com.ibm.jsse2.renegotiation.indicator set to OPTIONAL or default taken
IBMJSSE2 will not perform identity checking against the peer cert check during renegotiation per com.ibm.jsse2.renegotiation.peer.cert.check set to OFF or default
IBMJSSE2 will not allow unsafe server certificate change during renegotiation per jdk.tls.allowUnsafeServerCertChange set to FALSE or default
Is initial handshake: true
JsseJCE: Using KeyAgreement ECDH from provider IBMJCE version 1.2
JsseJCE: Using signature SHA1withECDSA from provider TBD via init
JsseJCE: Using signature NONEwithECDSA from provider TBD via init
JsseJCE: Using KeyFactory EC from provider IBMJCE version 1.2
JsseJCE: Using KeyPairGenerator EC from provider TBD via init
JsseJce: EC is available
Ignoring disabled cipher suite: SSL_RENEGO_PROTECTION_REQUEST for TLSv1
No available cipher suite for TLSv1
Thread-8, handling exception: javax.net.ssl.SSLHandshakeException: No appropriate protocol
Thread-8, SEND TLSv1 ALERT: fatal,
description = handshake_failure
" No hay un conjunto de cifrado disponible para TLSv1 "parece ser la raíz de mi problema.
Actualiza: Obtención de la fábrica predeterminada de sockets del servidor SSL SSLServerSocketFactory.getDefault()
) y los conjuntos de cifrado correspondientes predeterminados y compatibles getDefaultCipherSuites()
/ getSupportedCipherSuites()
) reveló que solo están disponibles los conjuntos de cifrado SSL:
SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA [supported]
SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA [default]
SSL_DHE_DSS_WITH_AES_128_CBC_SHA [default]
SSL_DHE_DSS_WITH_AES_128_CBC_SHA256 [supported]
SSL_DHE_DSS_WITH_AES_128_GCM_SHA256 [supported]
SSL_DHE_DSS_WITH_AES_256_CBC_SHA [default]
SSL_DHE_DSS_WITH_AES_256_CBC_SHA256 [supported]
SSL_DHE_DSS_WITH_AES_256_GCM_SHA384 [supported]
SSL_DHE_DSS_WITH_DES_CBC_SHA [default]
SSL_DHE_DSS_WITH_RC4_128_SHA [supported]
SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA [supported]
SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA [default]
SSL_DHE_RSA_WITH_AES_128_CBC_SHA [default]
SSL_DHE_RSA_WITH_AES_128_CBC_SHA256 [supported]
SSL_DHE_RSA_WITH_AES_128_GCM_SHA256 [supported]
SSL_DHE_RSA_WITH_AES_256_CBC_SHA [default]
SSL_DHE_RSA_WITH_AES_256_CBC_SHA256 [supported]
SSL_DHE_RSA_WITH_AES_256_GCM_SHA384 [supported]
SSL_DHE_RSA_WITH_DES_CBC_SHA [default]
SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA [supported]
SSL_DH_anon_EXPORT_WITH_RC4_40_MD5 [supported]
SSL_DH_anon_WITH_3DES_EDE_CBC_SHA [supported]
SSL_DH_anon_WITH_AES_128_CBC_SHA [supported]
SSL_DH_anon_WITH_AES_128_CBC_SHA256 [supported]
SSL_DH_anon_WITH_AES_128_GCM_SHA256 [supported]
SSL_DH_anon_WITH_AES_256_CBC_SHA [supported]
SSL_DH_anon_WITH_AES_256_CBC_SHA256 [supported]
SSL_DH_anon_WITH_AES_256_GCM_SHA384 [supported]
SSL_DH_anon_WITH_DES_CBC_SHA [supported]
SSL_DH_anon_WITH_RC4_128_MD5 [supported]
SSL_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA [supported]
SSL_ECDHE_ECDSA_WITH_AES_128_CBC_SHA [supported]
SSL_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 [supported]
SSL_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 [supported]
SSL_ECDHE_ECDSA_WITH_AES_256_CBC_SHA [supported]
SSL_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 [supported]
SSL_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 [supported]
SSL_ECDHE_ECDSA_WITH_NULL_SHA [supported]
SSL_ECDHE_ECDSA_WITH_RC4_128_SHA [supported]
SSL_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA [supported]
SSL_ECDHE_RSA_WITH_AES_128_CBC_SHA [supported]
SSL_ECDHE_RSA_WITH_AES_128_CBC_SHA256 [supported]
SSL_ECDHE_RSA_WITH_AES_128_GCM_SHA256 [supported]
SSL_ECDHE_RSA_WITH_AES_256_CBC_SHA [supported]
SSL_ECDHE_RSA_WITH_AES_256_CBC_SHA384 [supported]
SSL_ECDHE_RSA_WITH_AES_256_GCM_SHA384 [supported]
SSL_ECDHE_RSA_WITH_NULL_SHA [supported]
SSL_ECDHE_RSA_WITH_RC4_128_SHA [supported]
SSL_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA [supported]
SSL_ECDH_ECDSA_WITH_AES_128_CBC_SHA [supported]
SSL_ECDH_ECDSA_WITH_AES_128_CBC_SHA256 [supported]
SSL_ECDH_ECDSA_WITH_AES_128_GCM_SHA256 [supported]
SSL_ECDH_ECDSA_WITH_AES_256_CBC_SHA [supported]
SSL_ECDH_ECDSA_WITH_AES_256_CBC_SHA384 [supported]
SSL_ECDH_ECDSA_WITH_AES_256_GCM_SHA384 [supported]
SSL_ECDH_ECDSA_WITH_NULL_SHA [supported]
SSL_ECDH_ECDSA_WITH_RC4_128_SHA [supported]
SSL_ECDH_RSA_WITH_3DES_EDE_CBC_SHA [supported]
SSL_ECDH_RSA_WITH_AES_128_CBC_SHA [supported]
SSL_ECDH_RSA_WITH_AES_128_CBC_SHA256 [supported]
SSL_ECDH_RSA_WITH_AES_128_GCM_SHA256 [supported]
SSL_ECDH_RSA_WITH_AES_256_CBC_SHA [supported]
SSL_ECDH_RSA_WITH_AES_256_CBC_SHA384 [supported]
SSL_ECDH_RSA_WITH_AES_256_GCM_SHA384 [supported]
SSL_ECDH_RSA_WITH_NULL_SHA [supported]
SSL_ECDH_RSA_WITH_RC4_128_SHA [supported]
SSL_ECDH_anon_WITH_3DES_EDE_CBC_SHA [supported]
SSL_ECDH_anon_WITH_AES_128_CBC_SHA [supported]
SSL_ECDH_anon_WITH_AES_256_CBC_SHA [supported]
SSL_ECDH_anon_WITH_NULL_SHA [supported]
SSL_ECDH_anon_WITH_RC4_128_SHA [supported]
SSL_KRB5_EXPORT_WITH_DES_CBC_40_MD5 [supported]
SSL_KRB5_EXPORT_WITH_DES_CBC_40_SHA [supported]
SSL_KRB5_EXPORT_WITH_RC4_40_MD5 [supported]
SSL_KRB5_EXPORT_WITH_RC4_40_SHA [supported]
SSL_KRB5_WITH_3DES_EDE_CBC_MD5 [supported]
SSL_KRB5_WITH_3DES_EDE_CBC_SHA [supported]
SSL_KRB5_WITH_DES_CBC_MD5 [supported]
SSL_KRB5_WITH_DES_CBC_SHA [supported]
SSL_KRB5_WITH_RC4_128_MD5 [supported]
SSL_KRB5_WITH_RC4_128_SHA [supported]
SSL_RSA_EXPORT_WITH_DES40_CBC_SHA [supported]
SSL_RSA_EXPORT_WITH_RC4_40_MD5 [supported]
SSL_RSA_FIPS_WITH_3DES_EDE_CBC_SHA [default]
SSL_RSA_FIPS_WITH_DES_CBC_SHA [default]
SSL_RSA_WITH_3DES_EDE_CBC_SHA [default]
SSL_RSA_WITH_AES_128_CBC_SHA [default]
SSL_RSA_WITH_AES_128_CBC_SHA256 [supported]
SSL_RSA_WITH_AES_128_GCM_SHA256 [supported]
SSL_RSA_WITH_AES_256_CBC_SHA [default]
SSL_RSA_WITH_AES_256_CBC_SHA256 [supported]
SSL_RSA_WITH_AES_256_GCM_SHA384 [supported]
SSL_RSA_WITH_DES_CBC_SHA [default]
SSL_RSA_WITH_NULL_MD5 [supported]
SSL_RSA_WITH_NULL_SHA [supported]
SSL_RSA_WITH_NULL_SHA256 [supported]
SSL_RSA_WITH_RC4_128_MD5 [supported]
SSL_RSA_WITH_RC4_128_SHA [supported]
¿Alguien puede decirme cómo hacer que los conjuntos de cifrado TLS estén disponibles en la fábrica de sockets del servidor?