Java SSLHandshakeException:没有共同的密码套件

2024-04-12

我正在尝试使用 Java SSLSockets 将安全性应用于简单的聊天应用程序。

我创建了一个自签名 CA,并用它签署了两个证书(全部使用 RSA 密钥),一个用于服务器,一个用于客户端。之后,我将证书导入到服务器的密钥库和客户端的另一个密钥库。

CA :

openssl genrsa -out ca.key 1024 -rsa

openssl req -new -key ca.key -out ca.csr

openssl x509 -req -days 365 -in ca.csr -out ca.crt -signkey ca.key


SERVER CERTIFICATE:

openssl genrsa -out server.key 1024 -rsa

openssl req -new -key server.key -out server.csr

openssl ca -in server.csr -cert ca.crt -keyfile ca.key -out server.crt


CLIENT CERTIFICATE :

openssl genrsa -out client.key 1024 -rsa

openssl req -new -key client.key -out client.csr

openssl ca -in client.csr -cert ca.crt -keyfile ca.key -out client.crt



KEYSTORES:

keytool -import -keystore serverkeystore -file ca.crt -alias theCARoot

keytool -import -keystore serverkeystore -file server.crt -alias servercrt

keytool -import -keystore serverkeystore -file client.crt -alias clientcrt

keytool -import -keystore clientkeystore -file ca.crt  -alias theCARoot

keytool -import -keystore clientkeystore -file server.crt  -alias servercrt

keytool -import -keystore clientkeystore -file client.crt  -alias clientcrt

我想使用特定的密码,但显然所有受支持的密码都不起作用。

我的客户代码:

   import java.net.*;
import java.io.*;
import java.security.*;
import java.security.cert.CertificateException;
import javax.net.ssl.*;

public class ChatClient implements Runnable
{
    private SSLSocket socket           = null;
    private Thread thread              = null;
    private DataInputStream  console   = null;
    private DataOutputStream streamOut = null;
    private ChatClientThread client    = null;
    final String[] enabledCipherSuites = {"TLS_RSA_WITH_AES_256_CBC_SHA256"};
    final char[] passphrase = "123456".toCharArray();

    public ChatClient(String serverName, int serverPort)
    {
        System.out.println("Establishing connection to server...");
        try
        {
            SSLSocketFactory factory = null;
            SSLContext ctx = SSLContext.getInstance("TLS");
            KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());

            KeyStore ks= KeyStore.getInstance("JKS");
            ks.load(new FileInputStream("clientkeystore"), passphrase);
            kmf.init(ks, passphrase);


            KeyStore serverKey = KeyStore.getInstance("JKS");
            serverKey.load(new FileInputStream("serverkeystore"),passphrase);
            TrustManagerFactory trustManager = TrustManagerFactory.getInstance("SunX509");
            trustManager.init(serverKey);



            ctx.init(kmf.getKeyManagers(), trustManager.getTrustManagers(), null);
            factory = ctx.getSocketFactory();
            socket = (SSLSocket)factory.createSocket(serverName, serverPort);
            socket.setEnabledCipherSuites(enabledCipherSuites);
            start();
        }

        catch(UnknownHostException uhe)
        {
            // Host unkwnown
            System.out.println("Error establishing connection - host unknown: " + uhe.getMessage());
        }
        catch(IOException ioexception)
        {
            // Other error establishing connection
            System.out.println("Error establishing connection - unexpected exception: " + ioexception.getMessage());
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (KeyStoreException e) {
            e.printStackTrace();
        } catch (CertificateException e) {
            e.printStackTrace();
        } catch (UnrecoverableKeyException e) {
            e.printStackTrace();
        } catch (KeyManagementException e) {
            e.printStackTrace();
        }
    }

    public void run()
    {
        while (thread != null)
        {
            try
            {
                // Sends message from console to server
                streamOut.writeUTF(console.readLine());
                streamOut.flush();
            }

            catch(IOException ioexception)
            {
                System.out.println("Error sending string to server: " + ioexception.getMessage());
                stop();
            }
        }
    }


    public void handle(String msg)
    {
        // Receives message from server
        if (msg.equals(".quit"))
        {
            // Leaving, quit command
            System.out.println("Exiting...Please press RETURN to exit ...");
            stop();
        }
        else
            // else, writes message received from server to console
            System.out.println(msg);
    }

    // Inits new client thread
    public void start() throws IOException
    {
        console   = new DataInputStream(System.in);
        streamOut = new DataOutputStream(socket.getOutputStream());
        if (thread == null)
        {
            client = new ChatClientThread(this, socket);
            thread = new Thread(this);
            thread.start();
        }
    }

    // Stops client thread
    public void stop()
    {
        if (thread != null)
        {
            thread.stop();
            thread = null;
        }
        try
        {
            if (console   != null)  console.close();
            if (streamOut != null)  streamOut.close();
            if (socket    != null)  socket.close();
        }

        catch(IOException ioe)
        {
            System.out.println("Error closing thread..."); }
        client.close();
        client.stop();
    }


    public static void main(String args[])
    {
        ChatClient client = null;
        if (args.length != 2)
            // Displays correct usage syntax on stdout
            System.out.println("Usage: java ChatClient host port");
        else
            // Calls new client
            client = new ChatClient(args[0], Integer.parseInt(args[1]));
    }

}

class ChatClientThread extends Thread
{
    private SSLSocket        socket   = null;
    private ChatClient       client   = null;
    private DataInputStream  streamIn = null;

    public ChatClientThread(ChatClient _client, SSLSocket _socket)
    {
        client   = _client;
        socket   = _socket;
        open();
        start();
    }

    public void open()
    {
        try
        {
            streamIn  = new DataInputStream(socket.getInputStream());
        }
        catch(IOException ioe)
        {
            System.out.println("Error getting input stream: " + ioe);
            client.stop();
        }
    }

    public void close()
    {
        try
        {
            if (streamIn != null) streamIn.close();
        }

        catch(IOException ioe)
        {
            System.out.println("Error closing input stream: " + ioe);
        }
    }

    public void run()
    {
        while (true)
        {   try
        {
            client.handle(streamIn.readUTF());
        }
        catch(IOException ioe)
        {
            System.out.println("Listening error: " + ioe.getMessage());
            client.stop();
        }
        }
    }
}

对于服务器:

import java.net.*;
import java.io.*;
import java.security.*;
import java.security.cert.CertificateException;
import java.util.Arrays;
import javax.net.ServerSocketFactory;
import javax.net.ssl.*;

public class ChatServer implements Runnable
{
    private ChatServerThread clients[] = new ChatServerThread[20];
    private SSLServerSocket server_socket = null;
    private Thread thread = null;
    private int clientCount = 0;
    final String[] enabledCipherSuites = {"TLS_RSA_WITH_AES_256_CBC_SHA256"};
    final char[] passphrase = "123456".toCharArray();


    public ChatServer(int port)
    {
        try
        {
            // Binds to port and starts server
            System.out.println("Binding to port " + port);
            SSLContext ctx = SSLContext.getInstance("TLS");;
            KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
            KeyStore ks = KeyStore.getInstance("JKS");
            ks.load(new FileInputStream("serverkeystore"), passphrase);
            kmf.init(ks, passphrase);

            KeyStore serverKey = KeyStore.getInstance("JKS");
            serverKey.load(new FileInputStream("clientkeystore"),passphrase);
            TrustManagerFactory trustManager = TrustManagerFactory.getInstance("SunX509");
            trustManager.init(serverKey);

            ctx.init(kmf.getKeyManagers(), trustManager.getTrustManagers(), null);
            SSLServerSocketFactory ssf = ctx.getServerSocketFactory();
            server_socket = (SSLServerSocket) ssf.createServerSocket(port);
            server_socket.setEnabledCipherSuites(enabledCipherSuites);
            server_socket.setNeedClientAuth(true);
            System.out.println("Server started: " + server_socket);
            start();
        }
        catch(IOException ioexception)
        {
            // Error binding to port
            System.out.println("Binding error (port=" + port + "): " + ioexception.getMessage());
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (KeyStoreException e) {
            e.printStackTrace();
        } catch (CertificateException e) {
            e.printStackTrace();
        } catch (UnrecoverableKeyException e) {
            e.printStackTrace();
        } catch (KeyManagementException e) {
            e.printStackTrace();
        }
    }

    public void run()
    {
        while (thread != null)
        {
            try
            {
                // Adds new thread for new client
                System.out.println("Waiting for a client ...");
                addThread((SSLSocket)server_socket.accept());
            }
            catch(IOException ioexception)
            {
                System.out.println("Accept error: " + ioexception); stop();
            }
        }
    }

    public void start()
    {
        if (thread == null)
        {
            // Starts new thread for client
            thread = new Thread(this);
            thread.start();
        }
    }

    public void stop()
    {
        if (thread != null)
        {
            // Stops running thread for client
            thread.stop();
            thread = null;
        }
    }

    private int findClient(int ID)
    {
        // Returns client from id
        for (int i = 0; i < clientCount; i++)
            if (clients[i].getID() == ID)
                return i;
        return -1;
    }

    public synchronized void handle(int ID, String input)
    {
        if (input.equals(".quit"))
        {
            int leaving_id = findClient(ID);
            // Client exits
            clients[leaving_id].send(".quit");
            // Notify remaing users
            for (int i = 0; i < clientCount; i++)
                if (i!=leaving_id)
                    clients[i].send("Client " +ID + " exits..");
            remove(ID);
        }
        else
            // Brodcast message for every other client online
            for (int i = 0; i < clientCount; i++)
                clients[i].send(ID + ": " + input);
    }

    public synchronized void remove(int ID)
    {
        int pos = findClient(ID);

        if (pos >= 0)
        {
            // Removes thread for exiting client
            ChatServerThread toTerminate = clients[pos];
            System.out.println("Removing client thread " + ID + " at " + pos);
            if (pos < clientCount-1)
                for (int i = pos+1; i < clientCount; i++)
                    clients[i-1] = clients[i];
            clientCount--;

            try
            {
                toTerminate.close();
            }

            catch(IOException ioe)
            {
                System.out.println("Error closing thread: " + ioe);
            }

            toTerminate.stop();
        }
    }

    private void addThread(SSLSocket socket)
    {
        if (clientCount < clients.length)
        {
            // Adds thread for new accepted client
            System.out.println("Client accepted: " + socket);
            clients[clientCount] = new ChatServerThread(this, socket);

            try
            {
                clients[clientCount].open();
                clients[clientCount].start();
                clientCount++;
            }
            catch(IOException ioe)
            {
                System.out.println("Error opening thread: " + ioe);
            }
        }
        else
            System.out.println("Client refused: maximum " + clients.length + " reached.");
    }


    public static void main(String args[])
    {
        ChatServer server = null;

        if (args.length != 1)
            // Displays correct usage for server
            System.out.println("Usage: java ChatServer port");
        else
            // Calls new server
            server = new ChatServer(Integer.parseInt(args[0]));
    }

}

class ChatServerThread extends Thread
{
    private ChatServer       server    = null;
    private SSLSocket        socket    = null;
    private int              ID        = -1;
    private DataInputStream  streamIn  =  null;
    private DataOutputStream streamOut = null;


    public ChatServerThread(ChatServer _server, SSLSocket _socket)
    {
        super();
        server = _server;
        socket = _socket;
        ID     = socket.getPort();
    }

    // Sends message to client
    public void send(String msg)
    {
        try
        {
            streamOut.writeUTF(msg);
            streamOut.flush();
        }

        catch(IOException ioexception)
        {
            System.out.println(ID + " ERROR sending message: " + ioexception.getMessage());
            server.remove(ID);
            stop();
        }
    }

    // Gets id for client
    public int getID()
    {
        return ID;
    }

    // Runs thread
    public void run()
    {
        System.out.println("Server Thread " + ID + " running.");

        while (true)
        {
            try
            {
                server.handle(ID, streamIn.readUTF());
            }

            catch(IOException ioe)
            {
                System.out.println(ID + " ERROR reading: " + ioe.getMessage());
                server.remove(ID);
                stop();
            }
        }
    }


    // Opens thread
    public void open() throws IOException
    {
        streamIn = new DataInputStream(new BufferedInputStream(socket.getInputStream()));
        streamOut = new DataOutputStream(new BufferedOutputStream(socket.getOutputStream()));
    }

    // Closes thread
    public void close() throws IOException
    {
        if (socket != null)    socket.close();
        if (streamIn != null)  streamIn.close();
        if (streamOut != null) streamOut.close();
    }

}

抱歉,如果我的英语有点生疏。

我的操作系统是 OS X El Capitan,Java 版本是 1.8。

Here is the server's stack trace: 
/Library/Java/JavaVirtualMachines/jdk1.8.0_60.jdk/Contents/Home/bin/java -Djavax.net.debug=all -Didea.launcher.port=7536 "-Didea.launcher.bin.path=/Applications/IntelliJ IDEA 15.app/Contents/bin" -Dfile.encoding=UTF-8 -classpath "/Library/Java/JavaVirtualMachines/jdk1.8.0_60.jdk/Contents/Home/jre/lib/charsets.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_60.jdk/Contents/Home/jre/lib/deploy.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_60.jdk/Contents/Home/jre/lib/ext/cldrdata.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_60.jdk/Contents/Home/jre/lib/ext/dnsns.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_60.jdk/Contents/Home/jre/lib/ext/jaccess.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_60.jdk/Contents/Home/jre/lib/ext/jfxrt.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_60.jdk/Contents/Home/jre/lib/ext/localedata.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_60.jdk/Contents/Home/jre/lib/ext/nashorn.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_60.jdk/Contents/Home/jre/lib/ext/sunec.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_60.jdk/Contents/Home/jre/lib/ext/sunjce_provider.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_60.jdk/Contents/Home/jre/lib/ext/sunpkcs11.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_60.jdk/Contents/Home/jre/lib/ext/zipfs.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_60.jdk/Contents/Home/jre/lib/javaws.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_60.jdk/Contents/Home/jre/lib/jce.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_60.jdk/Contents/Home/jre/lib/jfr.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_60.jdk/Contents/Home/jre/lib/jfxswt.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_60.jdk/Contents/Home/jre/lib/jsse.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_60.jdk/Contents/Home/jre/lib/management-agent.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_60.jdk/Contents/Home/jre/lib/plugin.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_60.jdk/Contents/Home/jre/lib/resources.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_60.jdk/Contents/Home/jre/lib/rt.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_60.jdk/Contents/Home/lib/ant-javafx.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_60.jdk/Contents/Home/lib/dt.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_60.jdk/Contents/Home/lib/javafx-mx.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_60.jdk/Contents/Home/lib/jconsole.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_60.jdk/Contents/Home/lib/packager.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_60.jdk/Contents/Home/lib/sa-jdi.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_60.jdk/Contents/Home/lib/tools.jar:/Users/joaogoncalves/Dropbox/STI/out/production/STI Assignment 3:/Applications/IntelliJ IDEA 15.app/Contents/lib/idea_rt.jar" com.intellij.rt.execution.application.AppMain ChatServer 5000
Binding to port 5000
adding as trusted cert:
  Subject: CN=Joao Goncalves, OU=DEQ, O=UC, ST=Coimbra, C=PT
  Issuer:  CN=DEI, OU=DEI, O=UC, L=Coimbra, ST=Coimbra, C=PT
  Algorithm: RSA; Serial number: 0xc94895f3863a5c36
  Valid from Mon May 23 23:43:42 WEST 2016 until Tue May 23 23:43:42 WEST 2017

adding as trusted cert:
  Subject: CN=www.uc.pt, OU=DEM, O=UC, ST=Coimbra, C=PT
  Issuer:  CN=DEI, OU=DEI, O=UC, L=Coimbra, ST=Coimbra, C=PT
  Algorithm: RSA; Serial number: 0xc94895f3863a5c35
  Valid from Mon May 23 23:42:54 WEST 2016 until Tue May 23 23:42:54 WEST 2017

adding as trusted cert:
  Subject: CN=DEI, OU=DEI, O=UC, L=Coimbra, ST=Coimbra, C=PT
  Issuer:  CN=DEI, OU=DEI, O=UC, L=Coimbra, ST=Coimbra, C=PT
  Algorithm: RSA; Serial number: 0xdb931da4e1abec22
  Valid from Mon May 23 23:42:03 WEST 2016 until Tue May 23 23:42:03 WEST 2017

trigger seeding of SecureRandom
done seeding SecureRandom
Server started: [SSL: ServerSocket[addr=0.0.0.0/0.0.0.0,localport=5000]]
Waiting for a client ...
Allow unsafe renegotiation: false
Allow legacy hello messages: true
Is initial handshake: true
Is secure renegotiation: false
Client accepted: 74ce57fc[SSL_NULL_WITH_NULL_NULL: Socket[addr=/127.0.0.1,port=57519,localport=5000]]
Waiting for a client ...
Server Thread 57519 running.
Ignoring unsupported cipher suite: TLS_RSA_WITH_AES_256_CBC_SHA256 for TLSv1
No available cipher suite for TLSv1
Ignoring unsupported cipher suite: TLS_RSA_WITH_AES_256_CBC_SHA256 for TLSv1.1
No available cipher suite for TLSv1.1
[Raw read]: length = 5
0000: 16 03 03 00 52                                     ....R
[Raw read]: length = 82
0000: 01 00 00 4E 03 03 57 44   7B 3B B8 1E 77 88 AF 4E  ...N..WD.;..w..N
0010: C7 CA 73 CE AC 38 62 5D   18 BD 9A 16 7E 25 86 25  ..s..8b].....%.%
0020: 36 1C EF F5 B6 FF 00 00   02 00 3D 01 00 00 23 00  6.........=...#.
0030: 0D 00 1A 00 18 06 03 06   01 05 03 05 01 04 03 04  ................
0040: 01 03 03 03 01 02 03 02   01 02 02 01 01 FF 01 00  ................
0050: 01 00                                              ..
Thread-1, READ: TLSv1.2 Handshake, length = 82
*** ClientHello, TLSv1.2
RandomCookie:  GMT: 1464105787 bytes = { 184, 30, 119, 136, 175, 78, 199, 202, 115, 206, 172, 56, 98, 93, 24, 189, 154, 22, 126, 37, 134, 37, 54, 28, 239, 245, 182, 255 }
Session ID:  {}
Cipher Suites: [TLS_RSA_WITH_AES_256_CBC_SHA256]
Compression Methods:  { 0 }
Extension signature_algorithms, signature_algorithms: SHA512withECDSA, SHA512withRSA, SHA384withECDSA, SHA384withRSA, SHA256withECDSA, SHA256withRSA, SHA224withECDSA, SHA224withRSA, SHA1withECDSA, SHA1withRSA, SHA1withDSA, MD5withRSA
Extension renegotiation_info, renegotiated_connection: <empty>
***
[read] MD5 and SHA1 hashes:  len = 82
0000: 01 00 00 4E 03 03 57 44   7B 3B B8 1E 77 88 AF 4E  ...N..WD.;..w..N
0010: C7 CA 73 CE AC 38 62 5D   18 BD 9A 16 7E 25 86 25  ..s..8b].....%.%
0020: 36 1C EF F5 B6 FF 00 00   02 00 3D 01 00 00 23 00  6.........=...#.
0030: 0D 00 1A 00 18 06 03 06   01 05 03 05 01 04 03 04  ................
0040: 01 03 03 03 01 02 03 02   01 02 02 01 01 FF 01 00  ................
0050: 01 00                                              ..
%% Initialized:  [Session-1, SSL_NULL_WITH_NULL_NULL]
%% Invalidated:  [Session-1, SSL_NULL_WITH_NULL_NULL]
Thread-1, SEND TLSv1.2 ALERT:  fatal, description = handshake_failure
Thread-1, WRITE: TLSv1.2 Alert, length = 2
[Raw write]: length = 7
0000: 15 03 03 00 02 02 28                               ......(
Thread-1, called closeSocket()
Thread-1, handling exception: javax.net.ssl.SSLHandshakeException: no cipher suites in common
57519 ERROR reading: no cipher suites in common
Removing client thread 57519 at 0
Thread-1, called close()
Thread-1, called closeInternal(true)
Thread-1, called close()
Thread-1, called closeInternal(true)
Thread-1, called close()
Thread-1, called closeInternal(true)

Process finished with exit code 130

每个经过身份验证的一方的密钥库,始终是服务器,这里也是客户端,因为您指定了NeedClientAuth, 必须有私钥和证书,而不仅仅是证书。有两种方法可以做到这一点:

  • 将 OpenSSL 生成的私钥和相关证书转换为 PKCS#12,然后将 PKCS#12 转换为 JKS 或仅在 Java 中使用 PKCS#12(JCE 可以处理它,即使您指定 JKS,最新版本的 Java8 也可以! - 看http://www.oracle.com/technetwork/java/javase/8u60-relnotes-2620227.html http://www.oracle.com/technetwork/java/javase/8u60-relnotes-2620227.html在密钥库兼容模式下)。看:

    如何导入 Java 密钥库中现有的 x509 证书和私钥以在 SSL 中使用? https://stackoverflow.com/questions/906402/importing-an-existing-x509-certificate-and-private-key-in-java-keystore-to-use-i/8224863#8224863
    如何从现有证书 (abc.crt) 和 abc.key 文件创建密钥库? https://stackoverflow.com/questions/11952274/how-can-i-create-keystore-from-an-existing-certificate-abc-crt-and-abc-key-fil?lq=1
    导入 Java KeyStore 中的私钥/公钥证书对 https://stackoverflow.com/questions/17695297/importing-the-private-key-public-certificate-pair-in-the-java-keystore/17710626#17710626
    将证书从 pem 转换为 jks https://stackoverflow.com/questions/22296312/convert-certificate-from-pem-into-jks/22298627#22298627(披露:我的)
    如何从 cer 文件创建密钥库 https://stackoverflow.com/questions/29603989/how-to-create-keystore-from-cer-files/(披露:我的)

  • 在 Java 中生成 EE 私钥和 CSR,然后使用 OpenSSL(带有 CA 密钥和证书)颁发 EE 证书,并将证书导入回 Java 密钥库:

    keytool -keystore server.jks -genkeypair -keyalg RSA 
    # before j7 best to add -keysize 2048 see below 
    keytool -keystore server.jks -certreq >server.csr 
    openssl ca -in server.csr ... -out server.crt 
    # or submit the CSR to a real CA and get its response
    
    # then either install the chain all at once:
    cat server.crt ca.crt >temp
    keytool -keystore server.jks -importcert -file temp
    # and confirm (need temp so stdin available for confirm;
    # if using a public CA, can add -trustcacerts and use pipe instead)
    
    # or install the certs separately, top down:
    keytool -keystore server.jks -importcert -file ca.crt -alias ca
    # and confirm, THEN
    keytool -keystore server.jks -importcert -file server.crt 
    
    # (last) response must be 'Certificate reply was installed'
    # NOT merely 'Certificate was added' which means you messed up
    
    # and similarly for client
    

后一种方法(ca.crt 和 privatekey+server.crt 的单独条目)的优点是同一个文件可以用作密钥库和信任库,您不需要使用 serverkey 作为客户端信任,反之亦然。如果这些是真实的系统,这将是一个安全优势。

最后一点:您应该开始使用 RSA 2048 位密钥。自 2014 年以来,1024 位已被 NIST 和 CABforum 等权威机构禁止,尽管 Java 仍然接受它们,但大多数浏览器和许多其他工具已经对它们发出警告,并且可能很快就会拒绝它们。出于类似的原因,您应该至少使用 SHA256 签署证书——这可以在使用的配置文件中设置ca或者你可以只使用命令行标志-md sha256.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Java SSLHandshakeException:没有共同的密码套件 的相关文章

  • 存根方法时出现 InvalidUseOfMatchersException

    我有这个 TestNG 测试方法代码 InjectMocks private FilmeService filmeService new FilmeServiceImpl Mock private FilmeDAO filmeDao Bef
  • Java:无法从同一包中的不同类访问静态变量

    这很奇怪 因为我有一个可以访问 Frame dimension getWidth 的 Character 类 及其伙伴 getHeight 但是当我想在 Map 类中使用它时 Eclipse 强调了它并且无法给我反馈 运行该程序最终会出现
  • 是否有任何简单(且最新)的 Java 框架可用于在 Swing 应用程序中嵌入电影?

    我正在构建一个小型 Swing 应用程序 我想在其中嵌入一部电影 重要的是 这个应用程序是一个 WebStart 应用程序 并且该库应该能够打包在我启动的 jnlp 中 即 不依赖于本机库 我知道并尝试过 JMF 但我认为与其他框架相比 其
  • Java:在 eclipse 中导出到 .jar 文件

    我正在尝试将 Eclipse 中的程序导出到 jar 文件 在我的项目中 我添加了一些图片和 PDF s 当我导出到 jar 文件时 似乎只有main已编译并导出 我的意愿是如果可能的话将所有内容导出到 jar 文件 因为这样我想将其转换为
  • 通往楼梯顶部的可能路径

    这是一个非常经典的问题 我听说谷歌在他们的面试中使用过这个问题 问题 制定一个递归方法 打印从楼梯底部到楼梯顶部的所有可能的独特路径 有 n 个楼梯 您一次只能走 1 步或 2 步 示例输出 如果它是一个有 3 级楼梯的楼梯 1 1 1 2
  • 是否可以使用 Flying Saucer (XHTML-Renderer) 将 css 解析为类路径资源?

    我正在尝试将资源打包到 jar 中 但我无法让 Flying Saucer 在类路径上找到 css 我无法轻松构建 URL 来无缝解决此问题 https stackoverflow com questions 861500 url to l
  • 如何将 Mat (opencv) 转换为 INDArray (DL4J)?

    我希望任何人都可以帮助我解决这个任务 我正在处理一些图像分类并尝试将 OpenCv 3 2 0 和 DL4J 结合起来 我知道DL4J也包含Opencv 但我认为它没什么用 谁能帮我 如何转换成 INDArray 我尝试阅读一些问题here
  • 如何在代理后面安装 Eclipse Neon

    对于 Neon Eclipse 附带了一个安装程序 我在安装程序中找不到任何配置菜单 我的java版本是 java version java version 1 8 0 72 Java TM SE Runtime Environment b
  • 当客户端关闭连接时,Spring StreamingResponseBody 请求线程未清理

    我在控制器中有一个端点 它返回一个StreamingResponseBody 用于向客户端发送文件 其代码大致如下 RestController RequestMapping value api public class Controlle
  • ConcurrentHashMap 内部是如何工作的?

    我正在阅读有关 Java 并发性的 Oracle 官方文档 我想知道Collection由返回 public static
  • 是否可以通过编程方式查找 logback 日志文件?

    自动附加日志文件以支持电子邮件会很有用 我可以以编程方式设置路径 如以编程方式设置 Logback Appender 路径 https stackoverflow com questions 3803184 setting logback
  • 了解joda时间PeriodFormatter

    我以为我明白了 但显然我不明白 你能帮我通过这些单元测试吗 Test public void second assertEquals 00 00 01 OurDateTimeFormatter format 1000 Test public
  • 读取电子邮件的文本文件转换为 Javamail MimeMessage

    我有一个电子邮件原始来源的文本文件 直接从 gmail 复制 如果您单击 查看原始文件 您就会看到它 我想读入该文件并将其转换为 MimeMessage 如果您好奇为什么 我设置了 JavaMaildir 并且需要用电子邮件填充它的收件箱以
  • GWT 2.3 开发模式 - 托管模式 JSP 编译似乎不使用 java 1.5 兼容性

    无法编译 JSP 类 生成的 servlet 错误 DefaultMessage 上次更新 0 日期 中 0 时间 HH mm ss z 语法 错误 注释仅在源级别为 1 5 时可用 在尝试以开发模式在 Web 浏览器中打开我的 gwt 模
  • Freemarker 和 Struts 2,有时它计算为序列+扩展哈希

    首先我要说的是 使用 Struts2 Freemarker 真是太棒了 然而有些事情让我发疯 因为我不明白为什么会发生这种情况 我在这里问是因为也许其他人有一个想法可以分享 我有一个动作 有一个属性 说 private String myT
  • 流中的非终结符 forEach() ?

    有时 在处理 Java Stream 时 我发现自己需要一个非终端 forEach 来触发副作用但不终止处理 我怀疑我可以用 map item gt f item 之类的方法来做到这一点 其中方法 f 执行副作用并将项目返回到流中 但这似乎
  • java库维护数据库结构

    我的应用程序一直在开发 所以偶尔 当版本升级时 需要创建 更改 删除一些表 修改一些数据等 通常需要执行一些sql代码 是否有一个 Java 库可用于使我的数据库结构保持最新 通过分析类似 db structure version 信息并执
  • Java Swing:需要一个高质量的带有复选框的开发 JTree

    我一直在寻找一个 Tree 实现 其中包含复选框 其中 当您选择一个节点时 树中的所有后继节点都会被自动选择 当您取消选择一个节点时 树中其所有后继节点都会自动取消选择 当已经选择了父节点 并且从其后继之一中删除了选择时 节点颜色将发生变化
  • 使用按钮作为列表的渲染器

    我想使用一个更复杂的渲染器 其中包含列表的多个组件 更准确地说 类似于this https stackoverflow com questions 10840498 java swing 1 6 textinput like firefox
  • Java中HashMap和ArrayList的区别?

    在爪哇 ArrayList and HashMap被用作集合 但我不明白我们应该在哪些情况下使用ArrayList以及使用时间HashMap 他们两者之间的主要区别是什么 您具体询问的是 ArrayList 和 HashMap 但我认为要完

随机推荐

  • Oracle JDBC 和 Oracle CHAR 数据类型

    我在 Oracle JDBC 驱动程序的处理方面遇到了一个棘手的问题CHAR数据类型 让我们看一下这个简单的表格 create table x c char 4 insert into x c values a inserts a 所以当我
  • addEventListener,for(),索引。如何使用闭包? [复制]

    这个问题在这里已经有答案了 我有这个代码 var items this llistat getElementsByTagName a for var i 0 i lt items length i items i addEventListe
  • 如何使用MediaSession.setMediaButtonReceiver(PendingIntent)恢复播放

    当我的应用程序停止时单击耳机按钮时 我试图能够从我的应用程序开始音乐播放 我可以使用 MediaSession CallbackonMediaButtonEvent 或现已弃用的registerMediaButtonEventReceive
  • jQuery 未在引导模块中定义

    我想为我的网站使用 bootstrap 使用 node js 但我有以下错误 var www node modules bootstrap js transition js 59 jQuery ReferenceError jQuery 未
  • 在Android应用程序中集成视频文件作为应用程序背景

    我需要使用视频作为背景 首先 我将视频文件放在可绘制文件夹中 并称为背景LinearLayout在 main xml 中 但在运行该应用程序时 我只看到黑屏 然后我尝试使用VideoView并称其如下
  • Emacs - 调用时出错(服务器启动)

    我目前在 Windows Vista SP1 中使用 GNU Emacs 23 0 93 1 在我的 emacs 文件中 我调用 server start 这导致消息错误目录 emacs d server 不安全 有没有人见过这个并知道修复
  • 如何在c中将日期时间转换为unix时间戳?

    场景是 我使用 libexif 获取格式为 YYYY MM DD HH MM SS 的日期时间 为了最大限度地减少节省成本 我想将日期时间转换为unix时间戳或类似的值 只需要64位或32位 c 有什么明确的方法吗 你可以尝试组合使用str
  • .net core PGP加密解密

    上遇到错误void Encryption public void Encryption region PGP Encryption PgpEncryptionKeys encryptionKeys new PgpEncryptionKeys
  • 如何以人类可读的方式打开 Java .class 文件?

    我试图弄清楚 Java applet 类文件在幕后的作用 用记事本或文本板打开它只会显示一堆官样文章 有什么方法可以将其恢复为可读的格式 以便我可以尝试弄清楚它在做什么 环境 安装了 VS 2008 的 Windows jd gui htt
  • FFMPEG - 以特定时间间隔在视频上叠加多个视频

    我想以指定的时间间隔将多个视频叠加在单个视频上 尝试过不同的解决方案 但它不会像我一样工作 我使用下面的命令将视频叠加在视频上 String cmdWorking3 new String i yourRealPath i gifVideoF
  • 自动链接属性与实际链接不同的文本(setAutoLinkMask)

    例如 TextView tv TextView this findViewById R id tv tv setAutoLinkMask Linkify ALL tv setText visit website http www googl
  • 在 IIS7 上将多个域指向一个网站

    这与 SEO 没有任何关系 请不要发布任何有关 SEO 排名的内容 因为它不是这里的一个因素 我有2个网址 old websitename com 和 new websitename com 我需要在一定的时间内支持这两个 url 而不是在
  • 通过Python中的selenium驱动程序将图像导入谷歌表单

    我正在尝试将图像导入谷歌表单 我无法通过 xpath 将密钥传递给元素 看来这是一个隐藏的元素 我尝试执行脚本来取消隐藏它 但没有成功 也尝试过这个解决方案 如何使用 Selenium WebDriver python 访问隐藏的文件上传字
  • C++ 中的 Stringstream 解析单词和数字字符串

    我有这样的字符串 123加43次7 其中数字后面跟着字典中的单词 我知道我可以使用以下命令提取 int numbers gt gt 操作员 StringStream gt gt number 我可以拿到号码 然而 Stream 中仍然有该号
  • 将 JFrame 方向设置为从右到左!

    为了从右到左对齐我的 JFrame 我使用 setComponentOrientation ComponentOrientation RIGHT TO LEFT 但这仅当我使用 JFrame 的以下样式 装饰 时才有效 public cla
  • 如何使用 JaCoCo 忽略内部/嵌套类?

    我试图忽略一些生成的类 并且这些类被很好地忽略 但是 如果这些类具有内部类 则尽管父类被排除 但这些类仍然会被包含在内 这是我的配置
  • Asp.Net 3.5 路由到 Web 服务?

    我一直在寻找一种路线http www example com WebService asmx http www example com WebService asmx to http www example com service http
  • PhoneGap支持普通网络吗?

    phoneGap是否支持普通网页 如果支持的话我可以给我一个可以浏览的链接吗 thanks sri 当然 它可以加载到您现有的 UIWebView 实例中 或者加载到 ChildBrowser 中plugin http github com
  • 在 vim 中全局追加到具有匹配术语的行

    我确信这很容易 我只是缺少一两个字符 我需要在文件中搜索特定术语 当找到它时 我需要在该行添加一些内容 我想对比赛的每一行都这样做 要执行一次 我可以这样做 Thing to find s Stuff to append 简单的 如果我的
  • Java SSLHandshakeException:没有共同的密码套件

    我正在尝试使用 Java SSLSockets 将安全性应用于简单的聊天应用程序 我创建了一个自签名 CA 并用它签署了两个证书 全部使用 RSA 密钥 一个用于服务器 一个用于客户端 之后 我将证书导入到服务器的密钥库和客户端的另一个密钥