简体   繁体   English

java ssl tcp connection ok但收到服务器的数据不正确

[英]java ssl tcp connection ok but data received to server is incorrect

My problem is that I have ssl connection between java iso client and test server. 我的问题是我在java iso客户端和测试服务器之间有ssl连接。 Connection is ok, no problems with handshake, but server receives incorrect data. 连接正常,握手没问题,但服务器收到错误的数据。

As I see in log server receives just partial data during one read operation and some strange data also present in inputstream - maybe it is related to certificate information. 正如我在日志服务器中看到的那样,在一次读取操作期间只接收到部分数据,并且输入流中也存在一些奇怪的数据 - 可能与证书信息有关。

Note that without ssl this client and server works without any problems. 请注意,没有ssl,此客户端和服务器可以正常工作。 Also when I create jks standart certificate simple by java keyTool everything is ok and problem not happen. 此外,当我通过java keyTool创建简单的标准证书时,一切正常,问题不会发生。

But when I work with x509 problems happens no matter if I send certificate as parameter for server jvm by generating jks from cmd or use code below to generate jks in code. 但是当我处理x509问题时,无论我是否通过从cmd生成jks或使用下面的代码在代码中生成jks,将证书作为服务器jvm的参数发送。 Connection and handshake always ok, but data in inputstream is broken. 连接和握手总是正常,但输入流中的数据被破坏。

This how I get certificate using boucycastle library. 这是我如何使用boucycastle库获得证书。 Almost the same for client and server 客户端和服务器几乎相同

private SSLServerSocketFactory handleCertificate() throws KeyManagementException, KeyStoreException, NoSuchAlgorithmException, CertificateException, IOException, UnrecoverableKeyException {
    Security.addProvider(new BouncyCastleProvider());

    PEMReader pr = new PEMReader(new FileReader("p.pem"));
    X509CertificateObject cert = (X509CertificateObject) pr.readObject();

    PEMReader pr2 = new PEMReader(new FileReader("klient.cer"));
    X509CertificateObject cert2 = (X509CertificateObject) pr2.readObject();

    PEMReader kr = new PEMReader(new FileReader("001.key"),
            new PasswordFinder() {
                public char[] getPassword() {
                    return "password".toCharArray();
                }
            });

    KeyStore trustKeys = KeyStore.getInstance("JKS");
    trustKeys.load(null, "".toCharArray());
    trustKeys.setCertificateEntry("1", cert);

    KeyStore ksKeys = KeyStore.getInstance("JKS");
    ksKeys.load(null, "password".toCharArray());
    ksKeys.setCertificateEntry("1", cert2);

    org.bouncycastle.jce.provider.JCERSAPrivateCrtKey key;
    Object PK = kr.readObject();

    if (PK instanceof KeyPair) {
        key = (JCERSAPrivateCrtKey) ((KeyPair) PK).getPrivate();
    } else {
        key = (JCERSAPrivateCrtKey) PK;
    }

    ksKeys.setKeyEntry("1", key, "password".toCharArray(), new Certificate[] { cert2 });

    KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
    kmf.init(ksKeys, "password".toCharArray());

    TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");
    tmf.init(trustKeys);

    SSLContext sslContext = SSLContext.getInstance("SSLv3");
    sslContext.init(kmf.getKeyManagers(), tmf.getTrustManagers(), new java.security.SecureRandom());

    SSLServerSocketFactory factory = sslContext.getServerSocketFactory();
    return factory;
}

Code of server : 服务器代码:

    InputStream is = new BufferedInputStream(socket.getInputStream());
        while (!Thread.currentThread().isInterrupted()) {
            int size = 0;
            String mess_length = "";
            byte[] lenbuf = new byte[4];
            if (socket != null && socket.isConnected()) {
                socket.getInputStream().read(lenbuf);
                mess_length = new String(lenbuf);
                log.debug("Lenth of received message: " + mess_length);
            }
            int responseSize = 0;
            try {
                responseSize = Integer.valueOf(mess_length);
                size = responseSize;
            } catch (Exception int_e) {
                log.debug("Error of message lenth numbering: ", int_e);

            }
            byte[] buf = new byte[size];
            if (socket.isConnected() && socket.getInputStream().read(buf) == size) {
                log.debug("Message received.");
            }

            // -----------------------------------------------------------------------------------------------------------
            OutputStream out = new BufferedOutputStream(socket.getOutputStream());
            if ("echo".equals(EnvironmentProperties.getMode())) {
                log.info("responsing in echo mode");
                log.debug("Data to send from server: {} in connection id={}", new String(buf,
                        "UTF-8"), uuid);
                out.write(buf);
            }
            out.flush();
            bytesSet.clear();
            log.info("responded");

log from server: 从服务器登录:

17:37:26.166 [pool-1-thread-13] DEBUG r.b.t.app.server.ConnectionCallable - Mess
    age received.
    17:37:26.166 [pool-1-thread-13] INFO  r.b.t.app.server.ConnectionCallable - resp
    onsing in echo mode
    17:37:26.166 [pool-1-thread-13] DEBUG r.b.t.app.server.ConnectionCallable - Data
     to send from server:  in connection id=ee7f73ac-6be9-4e7b-876f-35d31845d69e
    17:37:26.166 [pool-1-thread-13] INFO  r.b.t.app.server.ConnectionCallable - resp
    onded
    17:37:26.166 [pool-1-thread-13] DEBUG r.b.t.app.server.ConnectionCallable - Lent
    h of received message: 200r
    17:37:26.167 [pool-1-thread-13] DEBUG r.b.t.app.server.ConnectionCallable - :
    java.lang.NumberFormatException: For input string: "200r"
            at java.lang.NumberFormatException.forInputString(Unknown Source) ~[na:1
    .8.0_05]
            at java.lang.Integer.parseInt(Unknown Source) ~[na:1.8.0_05]
            at java.lang.Integer.valueOf(Unknown Source) ~[na:1.8.0_05]
            at ru.billing.tcpipServerDummy.app.server.ConnectionCallable.call(Connec
    tionCallable.java:87) [TcpipServerDummy-0.0.1-SNAPSHOT.jar:na]
            at ru.billing.tcpipServerDummy.app.server.ConnectionCallable.call(Connec
    tionCallable.java:1) [TcpipServerDummy-0.0.1-SNAPSHOT.jar:na]
            at java.util.concurrent.FutureTask.run(Unknown Source) [na:1.8.0_05]
            at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source) [na
    :1.8.0_05]
            at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source) [n
    a:1.8.0_05]
            at java.lang.Thread.run(Unknown Source) [na:1.8.0_05]
    17:37:26.167 [pool-1-thread-13] DEBUG r.b.t.app.server.ConnectionCallable - Mess
    age received.
    17:37:26.167 [pool-1-thread-13] INFO  r.b.t.app.server.ConnectionCallable - resp
    onsing in echo mode
    17:37:26.167 [pool-1-thread-13] DEBUG r.b.t.app.server.ConnectionCallable - Data
     to send from server:  in connection id=ee7f73ac-6be9-4e7b-876f-35d31845d69e
    17:37:26.168 [pool-1-thread-13] INFO  r.b.t.app.server.ConnectionCallable - resp
    onded
    17:37:26.168 [pool-1-thread-13] DEBUG r.b.t.app.server.ConnectionCallable - Lent
    h of received message: 4♦А
    17:37:26.168 [pool-1-thread-13] DEBUG r.b.t.app.server.ConnectionCallable - ╬°шс
    ър яЁхюсЁрчютрэш  фышэ√ ёююс∙хэш :
    java.lang.NumberFormatException: For input string: "4♦А "
            at java.lang.NumberFormatException.forInputString(Unknown Source) ~[na:1
    .8.0_05]
            at java.lang.Integer.parseInt(Unknown Source) ~[na:1.8.0_05]
            at java.lang.Integer.valueOf(Unknown Source) ~[na:1.8.0_05]
            at ru.billing.tcpipServerDummy.app.server.ConnectionCallable.call(Connec
    tionCallable.java:87) [TcpipServerDummy-0.0.1-SNAPSHOT.jar:na]
            at ru.billing.tcpipServerDummy.app.server.ConnectionCallable.call(Connec
    tionCallable.java:1) [TcpipServerDummy-0.0.1-SNAPSHOT.jar:na]
            at java.util.concurrent.FutureTask.run(Unknown Source) [na:1.8.0_05]
            at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source) [na
    :1.8.0_05]
            at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source) [n
    a:1.8.0_05]
            at java.lang.Thread.run(Unknown Source) [na:1.8.0_05]
    17:37:26.168 [pool-1-thread-13] DEBUG r.b.t.app.server.ConnectionCallable - Mess
    age received.
    17:37:26.168 [pool-1-thread-13] INFO  r.b.t.app.server.ConnectionCallable - resp
    onsing in echo mode
    17:37:26.168 [pool-1-thread-13] DEBUG r.b.t.app.server.ConnectionCallable - Data
     to send from server:  in connection id=ee7f73ac-6be9-4e7b-876f-35d31845d69e
    17:37:26.168 [pool-1-thread-13] INFO  r.b.t.app.server.ConnectionCallable - resp
    onded
    17:37:26.168 [pool-1-thread-13] DEBUG r.b.t.app.server.ConnectionCallable - Lent
    h of received message: ┴А 2
    17:37:26.169 [pool-1-thread-13] DEBUG r.b.t.app.server.ConnectionCallable - ╬°шс
    ър яЁхюсЁрчютрэш  фышэ√ ёююс∙хэш :
    java.lang.NumberFormatException: For input string: "┴А 2"
            at java.lang.NumberFormatException.forInputString(Unknown Source) ~[na:1
    .8.0_05]
            at java.lang.Integer.parseInt(Unknown Source) ~[na:1.8.0_05]
            at java.lang.Integer.valueOf(Unknown Source) ~[na:1.8.0_05]
            at ru.billing.tcpipServerDummy.app.server.ConnectionCallable.call(Connec
    tionCallable.java:87) [TcpipServerDummy-0.0.1-SNAPSHOT.jar:na]
            at ru.billing.tcpipServerDummy.app.server.ConnectionCallable.call(Connec
    tionCallable.java:1) [TcpipServerDummy-0.0.1-SNAPSHOT.jar:na]
            at java.util.concurrent.FutureTask.run(Unknown Source) [na:1.8.0_05]
            at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source) [na
    :1.8.0_05]
            at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source) [n
    a:1.8.0_05]
            at java.lang.Thread.run(Unknown Source) [na:1.8.0_05]
    17:37:26.169 [pool-1-thread-13] DEBUG r.b.t.app.server.ConnectionCallable - Mess
    age received.
    17:37:26.169 [pool-1-thread-13] INFO  r.b.t.app.server.ConnectionCallable - resp
    onsing in echo mode
    17:37:26.169 [pool-1-thread-13] DEBUG r.b.t.app.server.ConnectionCallable - Data
     to send from server:  in connection id=ee7f73ac-6be9-4e7b-876f-35d31845d69e
    17:37:26.169 [pool-1-thread-13] INFO  r.b.t.app.server.ConnectionCallable - resp
    onded
    17:37:26.169 [pool-1-thread-13] DEBUG r.b.t.app.server.ConnectionCallable - Lent
    h of received message: 1194
    17:37:26.169 [pool-1-thread-13] DEBUG r.b.t.app.server.ConnectionCallable - ╧Ёхю
    сЁрчютрээр  фышээр ёююс∙хэш : 1194
    17:37:26.169 [pool-1-thread-13] INFO  r.b.t.app.server.ConnectionCallable - resp
    onsing in echo mode
    17:37:26.169 [pool-1-thread-13] DEBUG r.b.t.app.server.ConnectionCallable - Data
     to send from server: 6817121021052420000000000000000100000730173724000048001121
    101581111310001749439  749138         00809203123643













                     in connection id=ee7f73ac-6be9-4e7b-876f-35d31845d69e

Usual problem. 通常的问题。 You're ignoring the result returned by read() at one point and assuming it fills the length buffer, and then if the next read doesn't return exactly that number of bytes you're ignoring the bytes actually returned as well. 你忽略了read()在某一点返回的结果并假设它填充了长度缓冲区,然后如果下一次读取没有返回完全相同的字节数,你就会忽略实际返回的字节数。 You need to store the result returned by read() into a variable, and: 您需要将read()返回的结果存储到变量中,并且:

  • test it for -1, indicating end of stream 测试它为-1,表示流结束
  • otherwise keep looping until you get an entire message, however that's defined in your application protocol. 否则保持循环,直到你得到一个完整的消息,但这是在你的应用程序协议中定义的。

Other problems: 其他问题:

  • The Socket.isConnected() test here is pointless. 这里的Socket.isConnected()测试毫无意义。 It won't magically become false if the peer disconnects. 如果对等方断开连接,它将不会神奇地变为错误。 You have to detect that by getting -1 from read() , null from readLine(), etc. 您必须通过从read()获取-1,从readLine(),获取null等来检测它。

  • Ditto the socket == null test. 同样socket == null测试。 It already must be non-null otherwise you would have thrown an NPE in socket.getOutputStream(). 它必须是非null,否则你会在socket.getOutputStream().抛出一个NPE socket.getOutputStream().

  • You're creating a new BufferedOutputStream every time. 您每次都在创建一个新的BufferedOutputStream You should use one for the life of the socket. 您应该在套接字的生命周期中使用一个。

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

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