Java和C#应用程序之间的SSL通信

我的目标是在Java服务器和用C#编写的客户端之间建立安全通信。

java服务器代码:

System.setProperty("javax.net.ssl.keyStore","cert/mySrvKeystore"); System.setProperty("javax.net.ssl.keyStorePassword","myPassword"); SSLServerSocketFactory sslserversocketfactory = (SSLServerSocketFactory) SSLServerSocketFactory.getDefault(); SSLServerSocket sslserversocket = = (SSLServerSocket) sslserversocketfactory.createServerSocket(2389); while(true) { System.err.println("server w8 new connection"); try { SSLSocket sslsocket = (SSLSocket) sslserversocket.accept(); //sslsocket.startHandshake(); in = sslsocket.getInputStream(); out = sslsocket.getOutputStream(); out.flush(); String response = new String(receiveMessage()); while (response != "end") { System.out.println("Server recv="+response); response = new String(receiveMessage()); sendMessage(("echo="+response).getBytes()); } } catch (Exception exception) { exception.printStackTrace(); } } 

和用c#编写的客户端:

  client = new TcpClient() { SendTimeout = 5000, ReceiveTimeout = 5000 }; IPEndPoint serverEndPoint = new IPEndPoint(IPAddress.Parse(host), port); client.Connect(serverEndPoint); client.NoDelay = true; Console.WriteLine("Client connected."); // Create an SSL stream that will close the client's stream. SslStream sslStream = new SslStream(client.GetStream(), false, ValidateServerCertificate, null); // The server name must match the name on the server certificate. try { sslStream.AuthenticateAsClient("someName"); } catch (AuthenticationException error) { Console.WriteLine("Exception: {0}", error.Message); if (error.InnerException != null) { Console.WriteLine("Inner exception: {0}", error.InnerException.Message); } Console.WriteLine("Authentication failed - closing the connection."); client.Close(); return; } ASCIIEncoding ascii = new ASCIIEncoding(); SendData(ascii.GetBytes("Hello World")); 

  public static bool ValidateServerCertificate( object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors) { if (sslPolicyErrors == SslPolicyErrors.None) return true; Console.WriteLine("Certificate error: {0}", sslPolicyErrors); // Do not allow this client to communicate with unauthenticated servers. return false; } 

我得到以下错误:在c#中

  A first chance exception of type "System.Security.Authentication.AuthenticationException" occurred in System.dll Certificate error: RemoteCertificateChainErrors Exception: The remote certificate is invalid according to the validation procedure. Authentication failed - closing the connection. 

我知道问题可能是我使用不同类型的证书,但我不知道如何在java中使用X509Certificate制作标准的sslServerSocket。 有人可以帮助我,有很好的例子,或者一些建议我怎样才能实现我的目标?

PS我正在寻找bouncycastle库,导致它同时具有java和c#实现,但我想使用标准库,以及语言的内置function。

从您的示例中,您看起来不需要以编程方式生成证书和私钥。 您可以使用keytool在服务器密钥库中生成证书:

 keytool -genkey -alias myalias -keystore mykeystore.jks -dname "CN=www.example.com" 

或者更好,使用SAN扩展,如果您使用的是Java 7的keytool

 keytool -genkey -alias myalias -keystore mykeystore.jks -dname "CN=www.example.com" -ext san=dns:www.example.com 

在这里, www.example.com是客户端看到的主机名。 您可以在主题DN( dname )中添加其他内容,但请确保CN是主机名。

生成后,使用以下方法导出自签名证书:

 keytool -export myservercert.crt -alias myalias -keystore mykeystore.jks 

然后,您应该能够将其作为受信任的证书导入Windows证书存储区,而不是使用C#。