简体   繁体   English

与Glassfish3 / 4或Tomcat 8的双向(相互)SSL和自签名证书

[英]Two-way (mutual) SSL with Glassfish3/4 or Tomcat 8 and self-signed certificates

I'm trying to implement two-way (mutual) SSL authentication, but I constantly get the following exception either on Glassfish3/4 and Tomcat 8 servers (the stacktrace is from Tomcat 8): 我正在尝试实现双向(相互)SSL身份验证,但我经常在Glassfish3 / 4和Tomcat 8服务器上获得以下异常(stacktrace来自Tomcat 8):

10-Feb-2016 17:13:41.579 SEVERE [http-nio2-18443-exec-2] org.apache.tomcat.util.net.Nio2Endpoint$SocketProcessor.doRun Error running socket processor
java.lang.RuntimeException: Field length overflow, the field length (7189180) should be less than 65536
    at sun.security.ssl.Handshaker.checkThrown(Handshaker.java:1373)
    at sun.security.ssl.SSLEngineImpl.checkTaskThrown(SSLEngineImpl.java:529)
    at sun.security.ssl.SSLEngineImpl.readNetRecord(SSLEngineImpl.java:807)
    at sun.security.ssl.SSLEngineImpl.unwrap(SSLEngineImpl.java:775)
    at javax.net.ssl.SSLEngine.unwrap(SSLEngine.java:624)
    at org.apache.tomcat.util.net.SecureNio2Channel.handshakeUnwrap(SecureNio2Channel.java:394)
    at org.apache.tomcat.util.net.SecureNio2Channel.handshakeInternal(SecureNio2Channel.java:267)
    at org.apache.tomcat.util.net.SecureNio2Channel.handshake(SecureNio2Channel.java:204)
    at org.apache.tomcat.util.net.Nio2Endpoint$SocketProcessor.doRun(Nio2Endpoint.java:1064)
    at org.apache.tomcat.util.net.Nio2Endpoint$SocketProcessor.run(Nio2Endpoint.java:1046)
    at org.apache.tomcat.util.net.Nio2Endpoint.processSocket0(Nio2Endpoint.java:598)
    at org.apache.tomcat.util.net.Nio2Endpoint.processSocket(Nio2Endpoint.java:583)
    at org.apache.tomcat.util.net.SecureNio2Channel$1.completed(SecureNio2Channel.java:83)
    at org.apache.tomcat.util.net.SecureNio2Channel$1.completed(SecureNio2Channel.java:76)
    at sun.nio.ch.Invoker.invokeUnchecked(Invoker.java:126)
    at sun.nio.ch.Invoker$2.run(Invoker.java:218)
    at sun.nio.ch.AsynchronousChannelGroupImpl$1.run(AsynchronousChannelGroupImpl.java:112)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    at java.lang.Thread.run(Thread.java:745)

With long searching, I only found this link which shows the same problem but on JBoss. 经过长时间的搜索,我发现这个链接显示了同样的问题但是在JBoss上。 Is this really related to the size/number of entries in the key/truststore? 这真的与密钥/信任库中的条目大小/数量有关吗? I now have ~66.000 certificates stored, but as development goes on, we expect way more (like, hundreds of thousands). 我现在有存储〜66.000证书,但作为发展的推移,我们期待更多的方式 (如,几十万)。

With an almost empty keystore (only the server and one test client certificate in it), testing the SSL connection with curl is succesful... 使用几乎为空的密钥库(仅包含服务器和一个测试客户端证书),使用curl测试SSL连接是成功的...

UPDATE UPDATE

Okay, I think I figured out that it does related to truststore. 好吧,我想我发现它确实与truststore有关。 Here is the code snippet from sun.security.ssl.HandshakeMessage.CertificateRequest : 以下是sun.security.ssl.HandshakeMessage.CertificateRequest的代码片段:

        // put certificate_authorities
        int len = 0;
        for (int i = 0; i < authorities.length; i++) {
            len += authorities[i].length();
        }

        output.putInt16(len);

The exception is fired in the putInt() method, so I assume I really have too much certificates stored. 异常是在putInt()方法中触发的,所以我假设我确实存储了太多的证书。 I'm generating self-signed certificates right now, so I have to have every generated certificate as a CA on the server to trust the clients, and this must be the problem. 我现在正在生成自签名证书,因此我必须将每个生成的证书作为服务器上的CA来信任客户端,这一定是问题所在。 The question now is that is there a way to generate certificates from Java that are not self-signed (eg I could use glassfish's self-signed certificate as a CA - or can I)? 现在的问题是,有没有办法从Java生成自签名的证书(例如,我可以使用glassfish的自签名证书作为CA - 或者我可以)?

Okay, I made it to work by creating certificates with issuer set to server's own certificate (in Glassfish, with alias s1as particularly) and signing it with the server's private key. 好的,我通过创建颁发者设置为服务器自己的证书(在Glassfish中,特别是别名为s1as )创建证书并使用服务器的私钥对其进行签名。 Now I don't have to store anything on the server as it recognises clients because it knows their issuer as CA in its trustStore (essentially, itself). 现在我不必在服务器上存储任何东西,因为它识别客户端,因为它在其trustStore(本质上,它本身)中知道它们的发行者是CA.

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM