当前位置: 首页 > 知识库问答 >
问题:

java ssl tcp连接正常,但接收到服务器的数据不正确

东方权
2023-03-14

我的问题是,我在java iso客户端和测试服务器之间有ssl连接。连接正常,握手没有问题,但服务器接收到不正确的数据。

正如我在日志服务器中看到的,在一次读取操作期间只接收部分数据,并且输入流中也存在一些奇怪的数据-可能与证书信息有关。

请注意,如果没有ssl,此客户端和服务器工作时不会出现任何问题。而且,当我用java keyTool简单地创建jks标准证书时,一切都正常,问题也不会发生。

但是,当我使用x509时,无论是通过从cmd生成jks来发送证书作为服务器jvm的参数,还是使用下面的代码在代码中生成jks,都会出现问题。连接和握手始终正常,但inputstream中的数据已中断。

这就是我如何使用boucycastle库获取证书的方法。客户端和服务器几乎相同

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;
}

服务器代码:

    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");

来自服务器的日志:


    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

共有1个答案

段哲圣
2023-03-14

常见问题。您在某一点忽略了由read()返回的结果,并假设它填满了长度缓冲区,然后如果下一次读取没有返回准确的字节数,那么您也忽略了实际返回的字节数。您需要将read()返回的结果存储到变量中,并且:

  • 测试它为-1,表示流结束
  • 否则继续循环,直到您收到完整的消息,但这是在您的应用程序协议中定义的。

其他问题:

>

  • 插座。isConnected()此处测试没有意义。如果对等端断开连接,它不会神奇地变成错误。您必须通过从read()获取-1、从readLine()、等获取空值来检测。

    同上,套接字==null测试。它必须已经是非空的,否则您将在套接字中抛出一个NPE。getOutputStream()

    您每次都在创建一个新的BufferedOutputStream。您应该在套接字的生命周期中使用一个。

  •  类似资料:
    • 我正在两台本地服务器之间建立一个websocket进行开发。 一端,我的Ionic应用程序运行在http://localhost:8100/ 在另一端,我有一个Spring后端正在运行http://localhost:9080/(或http://127.0.0.1:9080) 连接已经建立,所以接下来我想用令牌发送一条消息到web套接字(我知道这可以在SockJS 1.1.0中设置连接时发送,但我

    • 我在使用 sse 推送数据时出现一个现象,使用 iOS、Android 手机和服务器建立 sse 连接,服务器同时通过连接推送 keep_alive 数据,测试过程发现 Android vsConsole 能够即时打印数据(即时接收到数据),但是 iOS 会在连接超时时刻统一打印之前接收到的数据。 因为客户端到服务器请求会经过 Nginx 服务器代理,所以考虑到是 Nginx 缓存的问题,但我在

    • 我正在运行2个spring boot应用程序:一个客户端和rest-api。客户机与rest-api通信,rest-API与mongodb数据库通信。所有3层都在docker容器中运行。 我启动容器,通常指定docker文件中公开的端口,并将它们映射到主机上的端口,例如:-p 7070:7070,其中7070是docker文件中公开的端口。 当我通过< code > Java-jar[applic

    • 问题内容: 我希望能够停止在Linux中的服务器套接字上进行侦听,并确保正确处理了从客户端角度打开的所有连接,并且没有突然关闭它们(即:接收ECONNRESET)。 即: 如果认为调用close()并处理已经接受的套接字就足够了,但是可以在内核积压中打开一些连接,如果在服务器套接字上调用close(),这些连接将突然关闭。 问题答案: 唯一可行的方法(我发现)是: 阻止添加更多客户端 在某处有一个

    • 我正在尝试连接两个docker容器,一个是posgresql,另一个是python flask应用程序。两者都链接正确,python应用程序中的所有连接变量都直接取自postgres容器中通过链接公开的连接变量,并且与检查postgresql容器时发现的连接变量相同。当我将psql与连接字符串中的精确参数一起使用时,即: 成功连接到postgres容器中的数据库,因此我知道postgres正在通过