如何连接到Java中的SSL服务器不发送证书?(How to connect to an SSL S

2019-10-22 13:20发布

我这里有一个开放式SSL服务器没有证书的运行如下的情况:OpenSSL的s_server -accept 4443 -nocert

如何连接到使用Java此服务器? 此外,我怎么开始我的服务器在Java中不接受任何证书?

我重视的Client.java和Server.java,我一直在使用的代码。

错误在运行在客户端附带的代码:

   javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure
    at sun.security.ssl.Alerts.getSSLException(Alerts.java:192)
    at sun.security.ssl.Alerts.getSSLException(Alerts.java:154)
    at sun.security.ssl.SSLSocketImpl.recvAlert(SSLSocketImpl.java:1959)
    at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1077)
    at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1312)
    at sun.security.ssl.SSLSocketImpl.writeRecord(SSLSocketImpl.java:702)
    at sun.security.ssl.AppOutputStream.write(AppOutputStream.java:122)
    at sun.nio.cs.StreamEncoder.writeBytes(StreamEncoder.java:221)
    at sun.nio.cs.StreamEncoder.implFlushBuffer(StreamEncoder.java:291)
    at sun.nio.cs.StreamEncoder.implFlush(StreamEncoder.java:295)
    at sun.nio.cs.StreamEncoder.flush(StreamEncoder.java:141)
    at java.io.OutputStreamWriter.flush(OutputStreamWriter.java:229)
    at Client.main(Client.java:27)

错误在服务器端:

ERROR
140387701290656:error:1408A0C1:SSL routines:SSL3_GET_CLIENT_HELLO:no shared cipher:s3_srvr.c:1358:
shutting down SSL
CONNECTION CLOSED
ACCEPT

Client.java

public class Client {
public static void main(String[] arstring) {
    try {
        SSLSocketFactory sslsocketfactory = (SSLSocketFactory) SSLSocketFactory.getDefault();
        SSLSocket sslsocket = (SSLSocket) sslsocketfactory.createSocket("localhost", 4443);            
        //sslsocket.setEnabledCipherSuites(sslsocket.getSupportedCipherSuites());
        sslsocket.setEnabledCipherSuites(new String[] { "TLS_DH_anon_WITH_AES_128_CBC_SHA" }); //Added upon suggestion from Steffan

        boolean test = sslsocket.isConnected();
        System.out.println(test);
        InputStream inputstream = sslsocket.getInputStream();
        InputStreamReader inputstreamreader = new InputStreamReader(inputstream);
        BufferedReader bufferedreader = new BufferedReader(inputstreamreader);
        System.out.println("1");
        OutputStream outputstream = sslsocket.getOutputStream();
        System.out.println("2");
        OutputStreamWriter outputstreamwriter = new OutputStreamWriter(outputstream,"UTF-8");
        String str = "hello\n";
        outputstreamwriter.write(str,0,str.length());
        //outputstreamwriter.flush();
        BufferedWriter bufferedwriter = new BufferedWriter(outputstreamwriter);

        String string = null;
        int count = 0;
        string = bufferedreader.readLine();
        while (true) {
            System.out.println(string);                
            System.out.flush();
            System.out.println(++count);
            string = bufferedreader.readLine();
            if (inputstream.available()==0)
                break;
            else{
                System.out.print("StreamData:");
                System.out.println(inputstream.available());
            }


        }
        System.out.println("Out");
    } catch (Exception exception) {
        exception.printStackTrace();
    }
}
}

Server.java

public class Server {
public static  void main(String[] arstring) {
    try {
        SSLServerSocketFactory sslServersocketFactory =
                (SSLServerSocketFactory) SSLServerSocketFactory.getDefault();
        SSLServerSocket sslServerSocket =
                (SSLServerSocket) sslServersocketFactory.createServerSocket(4443);
        SSLSocket sslSocket = (SSLSocket) sslServerSocket.accept();
        sslSocket.setEnabledCipherSuites(sslSocket.getSupportedCipherSuites());

        if (sslSocket.isConnected())
            System.out.println("Connected to a client");

        InputStream inputStream = sslSocket.getInputStream();
        InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
        BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
        String command = "";
        String response = "";

        while ((command = bufferedReader.readLine()) != null) {

                System.out.println("Command Recieved: "+command);

                if (command.toLowerCase().compareTo("hello")==0)
                    response = "Bingo !! You got it write!\n";
                else
                    response = "Type Hello to see a response\n";


                OutputStream outputStream = sslSocket.getOutputStream();
                OutputStreamWriter outputStreamWriter = new OutputStreamWriter(outputStream,"UTF-8");
                outputStreamWriter.write(response, 0, response.length());
                outputStreamWriter.flush();
        }
    } catch (Exception exception) {
        exception.printStackTrace();
    }
}

}

编辑:

我想我需要使用匿名DH密码,但它仍然没有工作。 可能是我做错了。 该代码已经被编辑过。

Answer 1:

如何连接到Java中的SSL服务器不发送证书?

如果其未发送证书,则其可能使用(1)预共享密钥密码套件,像TLS-SRP或TLS-PSK,或(2)其使用匿名的Diffie-Hellman之一。

预共享密钥加密套件通常的选择,因为它们提供了相互认证和信道绑定。

匿名的Diffie-Hellman通常是一个不错的选择,因为它缺乏服务器认证。


我这里有一个开放式SSL服务器没有证书的运行如下的情况:OpenSSL的s_server -accept 4443 -nocert

那么,你有它。


如何连接到使用Java此服务器? 此外,我怎么开始我的服务器在Java中不接受任何证书?

使用的密码套件,其中包括一个匿名交流,如:

  • LOVE-DES-SHA-CBC3
  • LOVE-AES128-沙
  • LOVE-AES256-沙
  • LOVE-SHA-CAMELLIA128
  • LOVE-SHA-CAMELLIA256
  • LOVE-SEED-沙
  • LOVE-AES128-SHA256
  • LOVE-AES256-SHA256
  • LOVE-AES128-GCM-SHA256
  • LOVE-AES256-GCM-SHA384

你可以得到的映射ADH-AES128-SHATLS_DH_anon_WITH_AES_128_CBC_SHA在OpenSSL的密码手册页。

你可以试试下面的命令:

openssl s_server -accept 4443 -tls1 -nocert -cipher "HIGH"

通过启用TLS1,你身边的步骤,其中一方或其他禁用的SSLv2和SSLv3的(这是一件好事),但任何潜在的问题,你只提供SSLv3的(这是一件坏事)。

该密码套件列表字符串"HIGH"包括ADH默认情况下(在生产中,通常你做"HIGH:!ADH:!RC4:!MD5..."



文章来源: How to connect to an SSL Server in Java that doesn't send a certificate?