在的XPages应用程序,我想为API第2使用Dropbox的的Java SDK(2.1.2)中获取有关我的Dropbox账户信息时,遇到出现SSLHandshakeException。下面的代码是用来获取相应的帐户对象:使用Dropbox的Java SDK的API为V2
String atoken = "****";
DbxRequestConfig rc = new DbxRequestConfig("****");
DbxClientV2 client = new DbxClientV2(rc,atoken);
DbxUserUsersRequests users = client.users();
FullAccount acc = users.getCurrentAccount(); // Exception raised here
最后一行引发以下异常:
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)
...
从我的结论堆栈跟踪该IBMJSSE2是用来处理安全提供商SSL握手。因此,我在非Domino JVM(JRE7)上运行了上面的代码,该JVM使用安全提供程序SunJSSE,并且没有任何问题。因此,这个问题必须与IBM的Domino JVM相关,但我无法弄清楚如何解决它。
任何人都可以帮助我或提供解决方案的提示吗?
附加信息:
Domino服务器的版本:9.0.1 FP4 HF70
Java运行版本:pwa6460sr16fp4-20150414_01(SR16 FP4)[22B8:0002-1E88]
JVM版本:JRE 1.6.0 IBM J9 2.4 Windows 7 amd64-64 jvmwa6460sr16fp4-20150406_242976(JIT enable d,启用AOT)J9VM - 20150406_242976 JIT - r9_20150402_88984 GC - GA24_Java6_SR16_20150406_1410_B242976
Domino JVM中已安装无限制的JCE策略文件。在IBMJSSE2安全提供
属性:
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_
例外的完整堆栈跟踪:
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)
...
更新:设置javax.net.debug=ssl:handshake:data
(由Jigar乔希的建议)之后,错误日志和跟踪日志提供了以下附加信息:
证书的主题为EMAILADDRESS = ****,CN = ****,O = ****,L = ****,ST = ****,C = ****,已发出由CN = ****,OU = ****,O = ****,C = ****,不受信任。验证失败,错误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">
不受信任的证书我自己,即使所有的证书和私钥被导入到我的密钥库。密钥库在非Domino JVM中运行的事实使我得出结论:密钥库文件应该是有效的。但是,在Domino JVM中运行代码时,证书仍然不受信任。
更新:调试输出(javax.net.debug=ssl:handshake
)的核心部分是
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
“没有可用的加密套件的TLSv1” 似乎是我的问题的根源。
更新:获取默认的SSL服务器套接字工厂(SSLServerSocketFactory.getDefault()
)和相应的默认和支持的加密套件(getDefaultCipherSuites()
/getSupportedCipherSuites()
)显示,只有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]
任何人都可以告诉我如何在服务器套接字工厂中提供TLS密码套件吗?
启用ssl调试并发送围绕握手的日志'-Djavax.net.debug = ssl:handshake:data' –
@JigarJoshi:感谢您的建议。错误日志现在说“证书...不可信,验证失败,错误3659”。我会对该错误进行一些谷歌研究,但当然,如果您有更多关于如何解决问题的提示,我将不胜感激:) –
如果您公开试图进行SSL连接,您可以粘贴URL吗? –