【问题标题】:Java NoClassDefFoundError With SSL Connection带有 SSL 连接的 Java NoClassDefFoundError
【发布时间】:2011-12-20 15:51:07
【问题描述】:

我们有一个应用程序使用 JAX-RPC 客户端库并在 Java 的旧版本 (1.4.2) 上运行,并且收到以下 SSL 错误:

java.lang.NoClassDefFoundError
    javax.crypto.Cipher.a(DashoA6275)
    javax.crypto.Cipher.getInstance(DashoA6275)
    com.sun.net.ssl.internal.ssl.SunJSSE_i.a(DashoA12275)
    com.sun.net.ssl.internal.ssl.CipherBox$JCECipherBox.<init>(DashoA12275)
    com.sun.net.ssl.internal.ssl.CipherRC4.a(DashoA12275)
    com.sun.net.ssl.internal.ssl.SunJSSE_h.a(DashoA12275)
    com.sun.net.ssl.internal.ssl.CipherSuite$BulkCipher.a(DashoA12275)
    com.sun.net.ssl.internal.ssl.SunJSSE_ax.c(DashoA12275)
    com.sun.net.ssl.internal.ssl.SSLSocketImpl.f(DashoA12275)
    com.sun.net.ssl.internal.ssl.SunJSSE_ax.a(DashoA12275)
    com.sun.net.ssl.internal.ssl.SunJSSE_az.j(DashoA12275)
    com.sun.net.ssl.internal.ssl.SunJSSE_az.a(DashoA12275)
    com.sun.net.ssl.internal.ssl.SunJSSE_az.a(DashoA12275)
    com.sun.net.ssl.internal.ssl.SunJSSE_ax.a(DashoA12275)
    com.sun.net.ssl.internal.ssl.SSLSocketImpl.a(DashoA12275)
    com.sun.net.ssl.internal.ssl.SSLSocketImpl.j(DashoA12275)
    com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(DashoA12275)
    sun.net.www.protocol.https.HttpsClient.afterConnect(DashoA12275)
    sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(DashoA12275)
    sun.net.www.protocol.http.HttpURLConnection.getOutputStream(HttpURLConnection.java:569)
    sun.net.www.protocol.https.HttpsURLConnectionImpl.getOutputStream(DashoA12275)
    com.sun.xml.rpc.client.http.HttpClientTransport.writeMessageToConnection(HttpClientTransport.java:278)
    com.sun.xml.rpc.client.http.HttpClientTransport.invoke(HttpClientTransport.java:64)
    com.sun.xml.rpc.client.StreamingSender._send(StreamingSender.java:69)
    [ ... trace continues into internal application code ... ]

这对我们之前有效,客户端库的唯一更改是与使用的身份验证协议相关的更改,需要更新到最新版本的 BouncyCastle。这些变化都比 SSL 协议更高,而且这个错误似乎甚至不涉及 BouncyCastle。

以前有没有人看到过这样的错误并且可能有任何想法或建议?我尝试将证书添加到cacerts。如果在 Java 1.6 上运行,这可以正常工作,但不幸的是,运行它的生产系统暂时仍与 Java 1.4 相关联。

此外,如果我们在没有 SSL 的情况下连接到我们的开发系统,我们的 JAX-RPC 代码以及它所执行的身份验证也可以正常工作。

[编辑 - 附加信息] 我现在可以看到新版本的 BouncyCastle 发生了一些冲突,从而导致了这个问题。我尝试使用古老的 (1.18) 版本,但似乎没有收到 SSL 错误,而是从我们的应用程序中获取了一个错误,因为它需要更新的算法。

【问题讨论】:

  • 您可能想查看 JRE 安全策略文件(%JAVA_HOME%/jre/lib/security/java.security 和 java.policy)以了解 Java 1.4 使用的类。 ...也许 SSL 证书使用了一些 Java 1.4 中不可用的新 Cypher,您可以通过查看 Java 使用的类之间的差异来发现这一点。
  • 您是否确定您使用的是 Java 1.4 的 BouncyCastle 库(它针对同一版本的库本身提供了不同的构建版本)。
  • 我认为这与 SSL 证书使用的密码无关。如果我从 BouncyCastle 1.46 恢复到我们之前使用的古老 1.18,则 SSL 连接工作正常。 (在这种情况下,我们的应用程序本身会中断,因为我们升级为使用更新的密码)
  • 试试不使用旧版本的Java? ;P
  • @nalroff 哦,我多么想。可悲的是,正如您所见,我无法控制这一点。 :-/

标签: java ssl noclassdeffounderror jce jsse


【解决方案1】:

所以,经过大量研究后,我终于发现,在我们的代码深处,我们将 BC 提供者作为第 1 号提供者插入。

Security.insertProviderAt(prov, 1);

而不是这样做更改为仅添加提供程序解决了问题。

Security.addProvider(prov);

【讨论】:

    【解决方案2】:

    javax.crypto.Cipher 位于名为 jce.jar 的单独(来自 rt.jar)JAR 文件中。可能类加载器找不到此文件,或者您的生产应用程序服务器没有在此文件上设置读取权限。

    【讨论】:

    • NoClassDefFoundError 表示它可以找到该类但不能找到该类导入的类。因此,它找到了Cipher 类。你错了。
    • 好点。我认为 Cipher 在异常消息中。无论如何,问题可能是由其他一些与安全相关的 jar 文件引起的。
    • 经过更多试验后,我发现它肯定与我们的 BouncyCastle 库有关。我切换回我们之前使用的(真正的)旧版本并且不再收到该错误,而是收到我希望从旧库的应用程序中收到的错误。至少这是一些进步!
    猜你喜欢
    • 2017-03-28
    • 1970-01-01
    • 1970-01-01
    • 2015-04-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-25
    • 2017-01-17
    • 1970-01-01
    相关资源
    最近更新 更多