Связь SSL между приложениями Java и C # - PullRequest
5 голосов
/ 06 марта 2012

Моя цель - сделать защищенный обмен данными между сервером 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.

Я знаю, что проблема может заключаться в том, что я использую различные типы сертификатов, но я не знаю, как сделать стандартный sslServerSocket с X509Certificate в Java. Может ли кто-нибудь помочь мне, с хорошим примером или советом, как мне достичь своей цели?

P.S. Я искал библиотеку bouncycastle, потому что она имеет реализацию java и c #, но я хотел бы использовать стандартные библиотеки и встроенную функциональность языков.

1 Ответ

2 голосов
/ 07 марта 2012

Из вашего примера не похоже, что вам нужно программно генерировать свой сертификат и закрытый ключ.Вы можете сгенерировать сертификат в хранилище ключей вашего сервера с помощью 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 #.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...