2017-02-20 48 views
0

我试图在客户端和服务器之间建立SSL连接。但任何时候我尝试从我的客户端连接,我得到一个javax.net.ssl.SSLHandshakeException:没有密码套件共同没有密码套件共同错误在我的服务器上。我已经生成了带签名证书的密钥库,并且在我的客户端和服务器上引用了密钥库。经过对这个问题的大量研究后,我已经厌倦了,并且在这个网站上的相关帖子没有帮助。javax.net.ssl.SSLHandshakeException:没有共同的密码套件没有共同的密码套件

这里是我的服务器代码

公共类ServerApplicationSSL {

public static void main(String[] args) { 
    boolean debug = true; 

    System.out.println("Waiting For Connection"); 

    int intSSLport = 4444; 

    { 
     Security.addProvider(new Provider()); 
     //Security.addProvider(new BouncyCastleProvider()); 

     //System.setProperty("javax.net.ssl.keyStore","C:\\SSLCERT\\NEWAEDCKSSKYE"); 
     //System.setProperty("javax.net.ssl.keyStorePassword", "skyebank"); 
    } 
    if (debug) { 
     System.setProperty("javax.net.debug", "all"); 
    } 
    FileWriter file = null; 
    try { 
     file = new FileWriter("C:\\SSLCERT\\Javalog.txt"); 

    } catch (Exception ee) { 
     //message = ee.getMessage(); 

    } 

    try { 

     KeyStore keystore = KeyStore.getInstance("JKS"); 
     keystore.load(new FileInputStream("C:\\SSLCERT\\NEWAEDCKSSKYE"), "skyebank".toCharArray()); 
     file.write("Incoming Connection\r\n"); 

     KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory 
       .getDefaultAlgorithm()); 
     kmf.init(keystore, "skyebank".toCharArray()); 

     TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509"); 
     tmf.init(keystore); 
     TrustManager[] trustManagers = tmf.getTrustManagers(); 

     SSLContext context = SSLContext.getInstance("TLS"); 
     context.init(kmf.getKeyManagers(), trustManagers, null); 

     SSLServerSocketFactory sslServerSocketfactory = (SSLServerSocketFactory) context.getServerSocketFactory(); 
     SSLServerSocket sslServerSocket = (SSLServerSocket) sslServerSocketfactory.createServerSocket(intSSLport); 

     SSLSocket sslSocket = (SSLSocket) sslServerSocket.accept(); 
     SSLServerSocket server_socket = (SSLServerSocket) sslServerSocket; 
     server_socket.setNeedClientAuth(true); 

     sslSocket.startHandshake(); 

     System.out.println("Connection Accepted"); 
     file.write("Connection Accepted\r\n"); 

     while (true) { 
      PrintWriter out = new PrintWriter(sslSocket.getOutputStream(), true); 
      //BufferedReader in = new BufferedReader(new InputStreamReader(sslSocket.getInputStream())); 
      String inputLine; 

      //while ((inputLine = in.readLine()) != null) { 
      out.println("Hello Client....Welcome"); 
      System.out.println("Hello Client....Welcome"); 
      //} 

      out.close(); 
      //in.close(); 
      sslSocket.close(); 
      sslServerSocket.close(); 
      file.flush(); 
      file.close(); 
     } 

    } catch (Exception exp) { 
     try { 
      System.out.println(exp.getMessage() + "\r\n"); 
      System.out.println(exp.getStackTrace() + "\r\n"); 
      file.write(exp.getMessage() + "\r\n"); 
      file.flush(); 
      file.close(); 
     } catch (Exception eee) { 
      //message = eee.getMessage(); 
     } 

    } 

} 

} 

这里是我的客户代码

public String MakeSSlCall(String meternum) { 
    String message = ""; 
    FileWriter file = null; 
    try { 
     file = new FileWriter("C:\\SSLCERT\\ClientJavalog.txt"); 

    } catch (Exception ee) { 
     message = ee.getMessage(); 
    } 
    try { 
     file.write("KeyStore Generated\r\n"); 
     KeyStore keystore = KeyStore.getInstance("JKS"); 
     keystore.load(new FileInputStream("C:\\SSLCERT\\NEWAEDCKSSKYE"), "skyebank".toCharArray()); 
     file.write("KeyStore Generated\r\n"); 
     Enumeration enumeration = keystore.aliases(); 
     while (enumeration.hasMoreElements()) { 
      String alias = (String) enumeration.nextElement(); 
      file.write("alias name: " + alias + "\r\n"); 
      keystore.getCertificate(alias); 
      file.write(keystore.getCertificate(alias).toString() + "\r\n"); 
     } 
     KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory 
       .getDefaultAlgorithm()); 
     kmf.init(keystore, "skyebank".toCharArray()); 
     TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509"); 
     tmf.init(keystore); 
     file.write("KeyStore Stored\r\n"); 
     SSLContext context = SSLContext.getInstance("SSL"); 
     TrustManager[] trustManagers = tmf.getTrustManagers(); 
     KeyManager[] AllKeysMan = kmf.getKeyManagers(); 

     file.write("Key Manager Length is " + AllKeysMan.length + "\r\n"); 

     for (int i = 0; i < AllKeysMan.length; i++) { 
      file.write("Key Manager At This Point is " + AllKeysMan[i] + "\r\n"); 
     } 
     context.init(kmf.getKeyManagers(), trustManagers, null); 
     SSLSocketFactory f = context.getSocketFactory(); 
     file.write("About to Connect to Ontech\r\n"); 
     SSLSocket c = (SSLSocket) f.createSocket("192.168.1.16", 4444); 
     file.write("Connection Established to 196.14.30.33 Port: 8462\r\n"); 
     file.write("About to Start Handshake\r\n"); 
     c.startHandshake(); 
     file.write("Handshake Established\r\n"); 
     file.flush(); 
     file.close(); 
     return "Connection Established"; 
    } catch (Exception e) { 
     try { 
      file.write("An Error Occured\r\n"); 
      file.write(e.getMessage() + "\r\n"); 
      file.flush(); 
      file.close(); 
     } catch (Exception eee) { 
      message = eee.getMessage(); 
     } 
     return "Connection Failed"; 
    } 
} 
} 

有人可以告诉我什么我做错了什么?

+0

我认为你在做什么是错的。对于客户端,您需要创建一个信任库并将服务器证书导入到该库中。你能试试吗?如果你想我可以给你一个示例工作代码。请让我知道。 –

+0

@RavindraRanwala我真的很感激示例工作代码 –

+0

我已经添加了一些示例代码,并提供了一些建议,因为我在您的代码中了解了这些代码。 –

回答

0

您将不得不为此目的使用SSLContext。查看我在下面的一个应用程序中实现的示例代码。客户端上下文意味着你成为客户端并呼叫一些后端。服务器上下文表示您接受客户端请求。

public class SSLUtil { 
    private static String KEY_STORE_TYPE = "JKS"; 
    private static String TRUST_STORE_TYPE = "JKS"; 
    private static String KEY_MANAGER_TYPE = "SunX509"; 
    private static String TRUST_MANAGER_TYPE = "SunX509"; 
    private static String PROTOCOL = "TLS"; 

    private static SSLContext serverSSLCtx = null; 
    private static SSLContext clientSSLCtx = null; 

    public static SSLContext createServerSSLContext(final String keyStoreLocation, 
                final String keyStorePwd) 
                      throws KeyStoreException, 
                      NoSuchAlgorithmException, 
                      CertificateException, 
                      FileNotFoundException, 
                      IOException, 
                      UnrecoverableKeyException, 
                      KeyManagementException { 
     if (serverSSLCtx == null) { 
      KeyStore keyStore = KeyStore.getInstance(KEY_STORE_TYPE); 
      keyStore.load(new FileInputStream(keyStoreLocation), keyStorePwd.toCharArray()); 
      KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KEY_MANAGER_TYPE); 
      keyManagerFactory.init(keyStore, keyStorePwd.toCharArray()); 
      serverSSLCtx = SSLContext.getInstance(PROTOCOL); 
      serverSSLCtx.init(keyManagerFactory.getKeyManagers(), null, null); 
     } 

     return serverSSLCtx; 
    } 

    public static SSLContext createClientSSLContext(final String trustStoreLocation, 
                final String trustStorePwd) 
                       throws KeyStoreException, 
                       NoSuchAlgorithmException, 
                       CertificateException, 
                       FileNotFoundException, 
                       IOException, 
                       KeyManagementException { 
     if (clientSSLCtx == null) { 
      KeyStore trustStore = KeyStore.getInstance(TRUST_STORE_TYPE); 
      trustStore.load(new FileInputStream(trustStoreLocation), trustStorePwd.toCharArray()); 
      TrustManagerFactory trustManagerFactory = 
                 TrustManagerFactory.getInstance(TRUST_MANAGER_TYPE); 
      trustManagerFactory.init(trustStore); 
      clientSSLCtx = SSLContext.getInstance(PROTOCOL); 
      clientSSLCtx.init(null, trustManagerFactory.getTrustManagers(), null); 
     } 

     return clientSSLCtx; 

    } 

} 

最后确保您将可信服务器证书导入到客户端密钥存储区。从字面上看,服务器和客户端应该有不同的密钥存储。由于我们在此信任服务器证书,客户端中使用的密钥存储区被称为客户端信任存储区。 This article可能会有所帮助。

+0

感谢您的回答,我不再收到密码套件错误。我认为这是因为我在我的服务器和客户端引用了相同的密钥库。然而,我现在得到这个执行我的服务器上的“javax.net.ssl.SSLHandshakeException:收到致命警报:certificate_unknown”和我的客户端上的这个异常“javax.net.ssl.SSLHandshakeException:sun.security.validator.ValidatorException:No trusted找到证书“ –

+0

您是否使用密钥工具导入命令将服务器证书导入到客户端信任库?看看https://docs.oracle.com/javase/tutorial/security/toolfilex/rstep1.html –

+0

是的,我有。我为客户端创建信任库时使用此命令 keytool -import -alias skyebankaedc -file skyebankaedc.cer -keystore mycerts -storepass skyebank并且还运行此命令来导入我自己的证书keytool -import -alias mucert -file mucert.cer -keystore mycerts -storepass myccert –