2

我的示例 webapp 代表其客户对 web 服务进行安全调用,这适用于我的本地环境,现在我想尝试在 Heroku 上部署它。

我已经设置了一个Procfile看起来像:

web: java $JAVA_OPTS -Djavax.net.debug=ssl -Djavax.net.ssl.trustStore=cacerts_custom.jks -Djavax.net.ssl.trustStorePassword=password -jar target/dependency/webapp-runner.jar --port $PORT target/*.war

由于-Djavax.net.debug=ssl我可以清楚地看到我添加到cacerts文件中的自定义服务器证书正在加载。

app web.1 - - trustStore is: cacerts_custom.jks
app web.1 - - trustStore type is : jks
app web.1 - - trustStore provider is :
app web.1 - - init truststore
app web.1 - - adding as trusted cert:
app web.1 - - Subject: me me me
app web.1 - - Issuer: me me me

但我仍然不断收到这些异常:

com.sun.jersey.api.client.ClientHandlerException: javax.net.ssl.SSLPeerUnverifiedException: peer not authenticated
  at com.sun.jersey.client.apache4.ApacheHttpClient4Handler.handle (ApacheHttpClient4Handler.java:184)
...
Caused by: javax.net.ssl.SSLPeerUnverifiedException: peer not authenticated
  at sun.security.ssl.SSLSessionImpl.getPeerCertificates(SSLSessionImpl.java:371)

app web.1 - - INFO: 1 * Client out-bound request
app web.1 - - 1 > GET https://webservice.com:80/gimmestuff
app web.1 - - 1 > Accept-Encoding: application/zip
app web.1 - -
app web.1 - - http-nio-31384-exec-5, setSoTimeout(0) called
app web.1 - - Allow unsafe renegotiation: false
app web.1 - - Allow legacy hello messages: true
app web.1 - - Is initial handshake: true
app web.1 - - Is secure renegotiation: false
app web.1 - - %% No cached client session
app web.1 - - *** ClientHello, TLSv1
app web.1 - - RandomCookie:  GMT: 1340484029 bytes = { 185, 85, 19, 4, 68, 226, 214, 134, 35, 143, 91, 59, 106, 156, 34, 20, 77, 75, 64, 92, 131, 186, 239, 23, 168, 188, 37, 157 }
app web.1 - - Session ID:  {}
app web.1 - - Cipher Suites: [SSL_RSA_WITH_RC4_128_MD5, SSL_RSA_WITH_RC4_128_SHA, TLS_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_DSS_WITH_AES_128_CBC_SHA, SSL_RSA_WITH_3DES_EDE_CBC_SHA, SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA, SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA, SSL_RSA_WITH_DES_CBC_SHA, SSL_DHE_RSA_WITH_DES_CBC_SHA, SSL_DHE_DSS_WITH_DES_CBC_SHA, SSL_RSA_EXPORT_WITH_RC4_40_MD5, SSL_RSA_EXPORT_WITH_DES40_CBC_SHA, SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA, SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA, TLS_EMPTY_RENEGOTIATION_INFO_SCSV]
app web.1 - - Compression Methods:  { 0 }
app web.1 - - ***
app web.1 - - http-nio-31384-exec-5, WRITE: TLSv1 Handshake, length = 75
app web.1 - - http-nio-31384-exec-5, WRITE: SSLv2 client hello message, length = 101
app web.1 - - http-nio-31384-exec-5, READ: TLSv1 Alert, length = 2
app web.1 - - http-nio-31384-exec-5, RECV TLSv1 ALERT:  fatal, handshake_failure
app web.1 - - http-nio-31384-exec-5, called closeSocket()
app web.1 - - http-nio-31384-exec-5, handling exception: javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure
app web.1 - - http-nio-31384-exec-5, IOException in getSession():  javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure
app web.1 - - http-nio-31384-exec-5, called close()
app web.1 - - http-nio-31384-exec-5, called closeInternal(true)
app web.1 - - http-nio-31384-exec-5, called close()
app web.1 - - http-nio-31384-exec-5, called closeInternal(true)

所以,在这一点上,我想知道:

  1. 我还能做些什么来尝试配置webapp-runner.jar使用 cacerts_custom.jks 文件?
  2. 如果 Procfile 或运行应用服务器的其他 Heroku 级别组件存在问题?
  3. 如果没有其他问题,我可能在我的代码中做错了什么?

更新#1:

我看到Using Apache httpclient for https在这里 httpclient 可能存在潜在问题,但我很难相信它今天仍然是一个问题。我会研究并回帖,但如果有人知道答案,请告诉我。


更新#2(2013 年 1 月 15 日):

如果我按照以下stackoverflow帖子中的内容进行操作:

收到 SSLHandshakeException:handshake_failure 尽管我的客户忽略了所有证书

它暗示以下日志是麻烦的迹象:

app[web.1]: http-nio-45949-exec-4, WRITE: TLSv1 Handshake, length = 75
app[web.1]: http-nio-45949-exec-4, WRITE: SSLv2 client hello message, length = 101
app[web.1]: http-nio-45949-exec-4, READ: TLSv1 Alert, length = 2
app[web.1]: http-nio-45949-exec-4, RECV TLSv1 ALERT:  fatal, handshake_failure

那么这里有什么错呢?提供服务器证书的一方?那不可能是因为我的本地托管的 web 应用程序可以与那一侧一起工作......除非它在我的本地环境中的 JDK 与 Heroku 上的 JDK 在其 SSL 握手和/或协议的实现方面完全不同?

4

1 回答 1

3

出于许可原因,Heroku 使用的 OpenJDK 构建不包括 Java Cryptography Extensions (JCE)。某些 SSL 证书需要处理 JCE。

您可以按照本文中的步骤将 JCE 包含在要包含在 JDK 中的应用程序中:https ://devcenter.heroku.com/articles/customizing-the-jdk

在此处下载 JCE:http ://www.oracle.com/technetwork/java/javase/downloads/index.html

于 2013-01-17T23:35:20.820 回答