SSL connector between .Net and Java with client authentication

I am trying to create an SSL Socket Server / Client between .NET and Java. In this case, my Socket SSL server will work in .net, and the client runs on Java under Linux. My problem is that the connection fails during the connection establishment, especially when the server requests a certificate from the client, the client cannot send something back and the connection does not work.

In .net I use sslStream to establish a connection, and in Java I use standard SSLSocket. Below are some snippets of code, but this is what I still have:

On the server side (Windows), I have a private certificate in the Personal / Certificates folders in the MMC. I have an open certificate from a client in trusted persons / certificates. Both certificates were issued by the same CA. The certificate chain for both certificates has several levels, but it is the same for both. The root-level certificate in the chain is also installed in the trusted certificates / certificates folder.

On the client side (Linux), I have a keystore that contains a private certificate that matches the public certificate installed on the server. I have a trust store that contains a public certificate from the server corresponding to the private server.

On the server side (.net), I use Socket, which performs asynchronous reading, and then it ends in SSLStream, the code fragment looks like this:

NetworkStream ns = new NetworkStream(socket, false); SslStream ssl = new SslStream(ns, true); ssl.AuthenticateAsServer(serverCertificate, true, SslProtocols.Default, true); 

Client code is pretty much standard code:

 SSLSocketFactory factory = (SSLSocketFactory) SSLSocketFactory.getDefault(); InetAddress addr = InetAddress.getByName(servername); SSLSocket socket = (SSLSocket) factory.createSocket(addr,port); socket.setUseClientMode(true); socket.setNeedClientAuth(true); socket.setWantClientAuth(true); socket.startHandshake(); os = new DataOutputStream(socket.getOutputStream()); is = new DataInputStream(socket.getInputStream()); byte[] outBuf = new byte[50]; os.write("SEND SOMETHING".getBytes("UTF-8")); is.read(outBuf); 

In java, I installed the correct varialbes to indicate trust and keystore with their password.

Now, following the SSL Handshake standard, here's what happens:

  • Clienthello
  • Serverhello
  • The server sends a public certificate
  • The client maps the public certificate to that in the trust store
  • Server sends certificate request
  • With a certificate request, the server sends a list of valid CAs, in this list only my root CA is sent (among a long list of other known CAs.).
  • The client certificate is null.
  • The server receives a null certificate from the client, thereby closing the connection.

And here it is, the client will not send a valid certificate back to the server. I have some questions about this:

Has anyone experienced something like this? Regarding this list of CAs sent by the server (Windows), how does .net determine what to send to the client? Is there any way to change this list? Do I need to send all the authority in the chain used to sign my certificate in this list of certificate authorities? or is root enough?

Am I missing something on either side of my code?

Any help would be greatly appreciated. IN

+4
source share
1 answer

The following two statements are useless on the client side (although they should not hurt):

 socket.setNeedClientAuth(true); socket.setWantClientAuth(true); 

The fact that you see the message "Certificate Request" and the message "Client Certificate" indicates that the server is configured correctly.

The most likely reason that comes to mind due to the lack of a certificate in the client certificate message is that the keystore (on the client side) may not be configured correctly. You may be interested in this answer to make sure that the client keystore is configured correctly. More specifically, you need to make sure that the private key for your client certificate has been imported into the same alias as the certificate chain (and that the chain is returned to the certificate authority announced in the certificate request message).

(As for the rest of your question, I'm not sure how to change the CA list sent by the server when using SslStream in C #. This earlier question would seem to suggest that there is no solution, although newer versions of .NET may solve the problem, since this question was asked. I could not find anything that could do this by looking at the documentation of the SslStream API and related classes, but that does not mean that it does not exist.)

+1
source

Source: https://habr.com/ru/post/1401682/


All Articles