[英]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()
返回的结果存储到变量中,并且:
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.