tomcat ssl客户端握手java错误

时间:2011-05-27 02:44:46

标签: java security tomcat ssl

错误:与ssl服务器的ssl握手。之后:客户端问候,服务器问候,证书,服务器密钥交换和服务器问候完成。 Web应用程序崩溃: java.lang.NoClassDefFoundError:无法初始化类javax.crypto.SunJCE_b

问题发生在:
tomcat 6.0.29

尝试以下JVM:
1.5,1.6_22,1.6_25
现在正在运行:
java -version java版“1.6.0_25” Java(TM)SE运行时环境(版本1.6.0_25-b06) Java HotSpot(TM)服务器VM(版本20.0-b11,混合模式)

操作系统:
uname -a
SunOS主机名5.10 Generic_118833-33 sun4v sparc sun4v

更多详情:

堆栈跟踪:

java.lang.NoClassDefFoundError: Could not initialize class javax.crypto.SunJCE_b
    javax.crypto.KeyGenerator.a(DashoA13*..)
javax.crypto.KeyGenerator.<init>(DashoA13*..)
javax.crypto.KeyGenerator.getInstance(DashoA13*..)
com.sun.net.ssl.internal.ssl.JsseJce.getKeyGenerator(JsseJce.java:223)
com.sun.net.ssl.internal.ssl.RSAClientKeyExchange.<init>(RSAClientKeyExchange.java:89)
com.sun.net.ssl.internal.ssl.ClientHandshaker.serverHelloDone(ClientHandshaker.java:744)
com.sun.net.ssl.internal.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:238)
com.sun.net.ssl.internal.ssl.Handshaker.processLoop(Handshaker.java:593)
com.sun.net.ssl.internal.ssl.Handshaker.process_record(Handshaker.java:529)
com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:893)
com.sun.net.ssl.internal.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1138)
com.sun.net.ssl.internal.ssl.SSLSocketImpl.writeRecord(SSLSocketImpl.java:632)
com.sun.net.ssl.internal.ssl.AppOutputStream.write(AppOutputStream.java:59)
com.sun.net.ssl.internal.ssl.AppOutputStream.write(AppOutputStream.java:73)
com.gosselinchristian.SSLPokeServlet.doGet(SSLPokeServlet.java:86)

代码:

protected void doGet(HttpServletRequest req, HttpServletResponse resp) {
    try {

        System.out.println(getClasspathString());
        System.out.println(getPropertiesString());

        SSLSocketFactory sslsocketfactory = (SSLSocketFactory) SSLSocketFactory
                .getDefault();
        SSLSocket sslsocket = (SSLSocket) sslsocketfactory.createSocket(
                "some_server", 443);

        InputStream in = sslsocket.getInputStream();
        OutputStream out = sslsocket.getOutputStream();



        // Write a test byte to get a reaction :)
        out.write(1);

        while (in.available() > 0) {
            System.out.print(in.read());
        }

        System.out.println("Successfully connected");

    } catch (Exception exception) {
        exception.printStackTrace();
    }
}

一些tomcat启动选项:

JAVA_OPTS='-server -Dapp.name=TEST -Dfile.encoding=ISO-8859-1 -XX:PermSize=128m  -XX:MaxPermSize=128m -Xms512m -Xmx2048m -Djava.protocol.handler.pkgs=com.sun.net.ssl.internal.www.protocol -Djavax.net.ssl.trustStore=/export/home/user/some_server_certs -Djavax.net.ssl.trustStorePassword=changeit -Djavax.net.debug=all'

相同的代码,相同的jvm,相同的证书在其他环境中工作。任何人都知道这可能出错的地方?

3 个答案:

答案 0 :(得分:1)

  

-Djava.protocol.handler.pkgs = com.sun.net.ssl.internal.www.protocol

一开始摆脱它,已经过时了7年。这仅适用于JDK 1.3。

您的JRE安装有问题。重新安装,然后确保Tomcat使用新安装的版本。

答案 1 :(得分:1)

javax.crypto.SunJCE_b类位于Sun JDK / JRE的<JAVA_HOME>/lib/jce.jar中。理想情况下,它应该由引导类加载器加载。加载此类失败表明Web应用程序的类加载机制存在问题,并且可能也适用于Tomcat。

您可能想要检查

  • 如果JRE / JDK包含此JAR。
  • 如果以某种方式设置CLASSPATH变量,则会导致加载不同的存档,或者根本不加载。这一点通常不适用,因为引导类加载器应该加载类,而不是系统类加载器(它依赖于这个环境变量)。
  • 如果您的任何应用程序使用AOP样式的技术来检测javax.crypto。*类。您可能希望将此类应用程序配置为(主要)从检测中排除这些类。简而言之,验证自定义类加载器实现。

答案 2 :(得分:1)

这是一篇很老的帖子,但无论如何我只是回应,以防万一与偶然发现这一点的人有关。我们在服务器上遇到此错误,问题实际上与打开文件限制有关。检查您的打开文件限制。如果它像1024那么你可能有同样的问题。增加Tomcat运行用户的打开文件限制。