As a team project I need to connect from a C# client to a Java 6.5 SSL server, however when I get to the stream.AuthenticateAsClient line it hangs.
C# connect code
public static void connect(string server, Int32 port)
{
try
{
client = new TcpClient(server, port);
stream = new SslStream(client.GetStream(), false);
stream.AuthenticateAsClient("MyCNfield");
...
...
If I connect to something like https://mail.google.com
and set MyCNfield
to mail.google.com
, it works fine, so I think it is the Java side.
The Java Init section is:
public void initSSL() throws IOException, KeyStoreException, NoSuchAlgorithmException,
CertificateException, UnrecoverableKeyException, KeyManagementException {
char[] passphrase = "scared".toCharArray();
System.out.println(java.security.KeyStore.getDefaultType());
boolean handshakedone=false;
KeyStore keystore1 = KeyStore.getInstance("jks");
FileInputStream fis = new FileInputStream("C:\\\\temp\\\\work.jks");
keystore1.load(fis, passphrase);
fis.close();
KeyStore ksTrust = KeyStore.getInstance("jks");
FileInputStream fis2 = new FileInputStream("C:\\\\temp\\\\work.jks");
ksTrust.load(fis2, passphrase);
KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
// KeyManager's decide which key material to use.
kmf.init(keystore1, passphrase);
// TrustManager's decide whether to allow connections.
TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");
tmf.init(ksTrust);
SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init( kmf.getKeyManagers(), tmf.getTrustManagers(), null);
SSLServerSocketFactory sslserversocketfactory =(SSLServerSocketFactory) sslContext.getServerSocketFactory();
sslserversocket =(SSLServerSocket) sslserversocketfactory.createServerSocket(2443);
sslserversocket.setUseClientMode(false);
//Context conte
ServerSocketFactory serversocketfactory =(ServerSocketFactory) sslContext.getServerSocketFactory();
// serverSocket = new ServerSocket(2443);
System.out.println("OK we are set up");
}
it gets called:
sslsocket = (SSLSocket) sslserversocket.accept();
and continues on, even though the connection was not fully authenticated.
What needs to be changed to fix this: the JKS has a cert MyCNfield
that is signed by a CA that I created. How do I either import the cert chain to my private CA in my C#, or how do I excange self-signed certs with Java and C#, and just throw out my current JKS?
You need to use the RemoteCertificateValidationCallback callback mechanism to provide certificate authentication. You shouldn't have closed the question, this is a valid question that many people may have. This answer was one of the first hits on a google search, thanks to the great SEO of stackoverflow, so it may lead people down the wrong path.
Use the RemoteCertificateValidationCallback callback.
And here is how you would use it with TCPClient: