gpt4 book ai didi

java - 通过 Java SSL 套接字写入时第一个字节丢失

转载 作者:太空宇宙 更新时间:2023-11-03 13:36:54 30 4
gpt4 key购买 nike

我正在以字节数组格式发送多个命令,并根据在典型的客户端/服务器通信中发送的命令接收响应。我的 Java 应用程序是在 Windows 7 上运行的客户端,我知道要发送什么命令以及我希望在响应中收到什么。但是,我对服务器源代码没有任何控制权或任何知识。

我遇到的问题是,在我发送的第二个命令或之后的任何命令中,数组的第一个字节被丢弃。当我发送第一个命令时,我得到了正确的响应,因为第一个字节没有被丢弃。当发送下一个命令或之后的任何命令时,第一个字节被丢弃,服务器没有响应,因为命令的格式不正确,服务器无法识别。

我正在通过 Java SSLSocket DataOutputStream 发送这些命令,当然我正在接收 DataInputStream 上的响应。我首先与服务器进行握手,握手成功后继续。此时是我发送第一个命令并收到此处以十六进制显示的响应的时候。:

Sending: 01 03 03 
Receive: 01 0e fd 85 02 09 01 01 04 01 06

正在发送的下一个命令:

Sending: 01 48 65 6c 6c 6f

但这是我没有收到服务器响应的地方。

打印出 javax.net.debug 输出时,我可以看到第一个字节“01”确实丢失或丢失了。

Padded plaintext before ENCRYPTION:  len = 32
0000: 48 65 6C 6C 6F FE 57 F9 4A 29 13 8F 2B AB 71 A3 Hello.W.J)..+.q.
0010: 16 12 29 FF D5 DE 12 48 8B 06 06 06 06 06 06 06 ..)....H........
main, WRITE: TLSv1 Application Data, length = 32
[Raw write]: length = 37
0000: 17 03 01 00 20 34 42 ED 88 FC 41 2D 13 1A FD BA .... 4B...A-....
0010: 64 0E 9D C7 FE 11 76 96 48 09 A6 BC B2 BC 0E FA d.....v.H.......
0020: C8 5B 79 4B 82 .[yK.

以下是我的源代码:

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManagerFactory;
import javax.net.ssl.HandshakeCompletedEvent;
import javax.net.ssl.HandshakeCompletedListener;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.X509TrustManager;
import javax.net.ssl.TrustManager;
import java.security.KeyStore;

public class SSLSocketTest
{
private SSLSocket sslSocket = null;
private SSLSocketFactory sslSocketFactory = null;
private String ipAddress = "192.168.100.99";
private int port = 9999;

DataOutputStream dataOS = null;
DataInputStream dataIS = null;

private boolean handshakeSuccessful = false;

public static void main(String[] args)
{
SSLSocketTest sslSocketTest = new SSLSocketTest();
sslSocketTest.sslSocketConnect();
}

SSLSocketTest()
{
System.setProperty("javax.net.debug", "all");

try{
File certFile = new File("cacerts");

KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
char[] certPassword = "changeit".toCharArray();
InputStream fileIS = new FileInputStream(certFile);
keyStore.load(fileIS, certPassword);
fileIS.close();

SSLContext sslContext = SSLContext.getInstance("TLSv1");

TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
trustManagerFactory.init(keyStore);
X509TrustManager defaultTrustManager = (X509TrustManager)trustManagerFactory.getTrustManagers()[0];

sslContext.init(null, new TrustManager[] {defaultTrustManager}, null);
sslSocketFactory = sslContext.getSocketFactory();
}catch(Exception e){
e.printStackTrace();
}
}

public void sslSocketConnect()
{
try{
sslSocket = (SSLSocket) sslSocketFactory.createSocket(ipAddress, port);

dataOS = new DataOutputStream(sslSocket.getOutputStream());
dataIS = new DataInputStream(sslSocket.getInputStream());

sslSocket.setSoTimeout(15000);

//Handshake
sslSocket.addHandshakeCompletedListener(new MyHandshakeListener());
sslSocket.startHandshake();
while(!handshakeSuccessful)
{
Thread.sleep(100);
}

//Sending commands
byte[] firstCommand = new byte[]{(byte)0x01, (byte)0x03, (byte)0x03};

String[] firstCommandResponse = processCommand(firstCommand);

byte[] secondCommand = new byte[]{(byte)0x01, (byte)0x48, (byte)0x65, (byte)0x6C, (byte)0x6C, (byte)0x6F};

String[] secondCommandResponse = processCommand(secondCommand);

disconnect();
}catch(Exception e){
e.printStackTrace();
}
}

public void disconnect()
{
try{
byte[] endConnection = new byte[]{(byte)0x01, (byte)0x01, (byte)0x02, (byte)0x03};

processCommand(endConnection);

dataOS.close();
dataIS.close();
sslSocket.close();
}catch (Exception e){
e.printStackTrace();
}
}

public String[] processCommand(byte[] command)
{
String[] returnResponse = null;

byte[] commandResponse = new byte[120];
byte[] trimCommandResponse;

try{
int commandResponseLength = -1;
int errorCount = 0;

while(commandResponseLength == -1)
{
StringBuilder cmdStr = new StringBuilder();
cmdStr.append("Sending: ");
for(int i=0; i<command.length; i++)
{
cmdStr.append(fixHexStringData(Integer.toHexString(command[i])) + " ");
}
System.out.println(cmdStr.toString());

dataOS.write(command, 0, command.length);
dataOS.flush();

commandResponseLength = dataIS.read(commandResponse);

errorCount++;
if(errorCount == 3)
{
throw new Exception();
}
}

returnResponse = new String[commandResponseLength];
trimCommandResponse = new byte[commandResponseLength];

//Getting Reponse Data
for(int i=0; i<commandResponseLength; i++)
{
returnResponse[i] = fixHexStringData(Integer.toHexString(commandResponse[i]));
trimCommandResponse[i] = commandResponse[i];
}

StringBuilder rcvStr = new StringBuilder();
rcvStr.append("Receive: ");
for(int i=0; i<returnResponse.length; i++)
{
rcvStr.append(returnResponse[i] + " ");
}
System.out.println(rcvStr.toString());

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

return returnResponse;
}

private String fixHexStringData(String dataByte)
{
if(dataByte.length() < 2)
{
dataByte = "0" + dataByte;
}
else if(dataByte.length() > 2)
{
dataByte = dataByte.substring(dataByte.length()-2);
}
return dataByte;
}

class MyHandshakeListener implements HandshakeCompletedListener
{
public void handshakeCompleted(HandshakeCompletedEvent e)
{
System.out.println("Handshake succesful!");

handshakeSuccessful = true;
}
}
}

我的问题是:

  1. 我是否遗漏了写出字节数组的步骤?我已经通过标准 Java Socket 完成了此操作,没有任何问题,那么通过 SSL Socket 编写与标准 Socket 不同吗?我找过这个,但没有发现任何不同之处。
  2. 这可能是证书问题吗?如果握手和第一个命令成功,是否意味着此时已经建立了通信并且超出了证书?
  3. 服务器会影响这个吗?如果是这样,这背后的原因可能是什么?如果将字节数组写入 DataOutputStream 是在客户端,并且第一个字节被丢弃,那么服务器对客户端有什么影响?
  4. 这可能是 JVM 错误吗?

最佳答案

看起来这实际上是 JSSE 实现的一个函数,它在两个数据包之间拆分数据。第一个字节进入一个数据包,其余字节进入下一个数据包。更多详情请访问 this answer

您应该能够通过包含来覆盖此功能

System.setProperty("jsse.enableCBCProtection", "false");

关于java - 通过 Java SSL 套接字写入时第一个字节丢失,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37191724/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com