Java和C#应用程序之间的SSL通信 [英] SSL communication between Java and C# applications

查看:111
本文介绍了Java和C#应用程序之间的SSL通信的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

My goal is to make a secure communication between a Java server and client written in C#.

java服务器代码:

java server code:

  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#

and i get the following errors: in 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。有人可以帮助我,有很好的例子,或者一些建议我如何达到我的目标?

I know that the issue can be the fact that i use different types of certificates, but i don't know how to make a standard sslServerSocket with X509Certificate in java. Can some one help me, with good example, or some advice how can i reach my goal ?

P.S。我正在寻找bouncycastle库,因为它同时具有java和c#实现,但我想使用标准库和语言的内置功能。<​​/ p>

P.S. I was looking to bouncycastle library, causes it has both java, and c# implementation, but i would like to use standard libraries, and built-in functionality of the languages.

推荐答案

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

From your example, it doesn't look like you need to generate your certificate and private key programmatically. You can generate a certificate in your server keystore with keytool:

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

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

Or better, with the SAN extension too, if you're using Java 7's 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 是主机名。

Here, www.example.com is the host name as seen by the client. You can add other things in the Subject DN (dname), but make sure the CN is the host name.

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

Once it's generated, export your self-signed certificate using:

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

然后你应该可以导入它作为Windows证书存储中的受信任证书,可以使用C#。

You should then be able to import it as a trusted certificate in your Windows certificate store from use from C#.

这篇关于Java和C#应用程序之间的SSL通信的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆