C#客户端通过SSL连接到Java服务器

作为一个团队项目,我需要从C#客户端连接到Java 6.5 SSL服务器,但是当我到达stream.AuthenticateAsClient行时,它会挂起。

C#连接代码

public static void connect(string server, Int32 port) { try { client = new TcpClient(server, port); stream = new SslStream(client.GetStream(), false); stream.AuthenticateAsClient("MyCNfield"); ... ... 

如果我连接到像https://mail.google.com这样的东西并将MyCNfield设置为mail.google.com ,它可以正常工作,所以我认为它是Java方面。

Java Init部分是:

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

它被称为:

 sslsocket = (SSLSocket) sslserversocket.accept(); 

并继续,即使连接未完全validation。

需要更改以解决此问题:JKS具有由我创建的CA签名的证书MyCNfield 。 如何在我的C#中将证书链导入我的私有CA,或者如何使用Java和C#强制使用自签名证书,并抛弃我当前的JKS?

您需要使用RemoteCertificateValidationCallback回调机制来提供证书身份validation。 你不应该关闭这个问题,这是许多人可能有的问题。 这个答案是谷歌搜索的第一个点击之一,这要归功于stackoverflow的优秀搜索引擎优化,所以它可能会导致人们走上错误的道路。

使用RemoteCertificateValidationCallback回调。

 private readonly bool allowSsl; // callback used to validate the certificate in an SSL conversation private static bool ValidateRemoteCertificate( object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors policyErrors ) { if (allowSsl) { // allow any certificate... return true; } else { return policyErrors == SslPolicyErrors.None; } } 

以下是如何在TCPClient中使用它:

 TcpClient client = new TcpClient(machineName,443); Console.WriteLine("Client connected."); // Create an SSL stream, specifying the callback above. SslStream sslStream = new SslStream( client.GetStream(), false, new RemoteCertificateValidationCallback (ValidateRemoteCertificate), null );