2016-10-13 11 views
0

SSLソケットを使用してクライアント - サーバーソケット接続を確立する際に問題が発生しています。私はまだSSL暗号化と証明書とキーストアの処理を学んでいます。 - SSLReverseEchoer.javaSSLソケットのヘルプ - javax.net.ssl.SSLHandshakeException:致命的なアラートを受信しました:certificate_unknown

import java.io.*; 
import java.net.*; 
import java.security.*; 
import javax.net.ssl.*; 
import org.bouncycastle.jce.provider.BouncyCastleProvider; 

public class SSLReverseEchoer { 
    public static void main(String[] args) { 
    String ksName = "sslkeystore.jks"; 
    String keystorePass = "sslkeystorepassword"; 
    char ksPass[] = keystorePass.toCharArray(); 

    int sslPort = 9099; 

    Security.addProvider(new BouncyCastleProvider()); 

    File file = new File(ksName); 
    String absPath = file.getAbsolutePath(); 

    System.setProperty("javax.net.ssl.keyStore", absPath); 
    System.setProperty("javax.net.ssl.keyStorePassword", "sslkeystorepassword"); 

    try { 

     //Get keystore w/ password 
     KeyStore ks = KeyStore.getInstance("JKS"); 
     ks.load(new FileInputStream(ksName), ksPass); 

     //Trust Manager 
     TrustManagerFactory tmf = TrustManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()); 
     tmf.init(ks); 

     KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509"); 
     kmf.init(ks, ksPass); 

     SSLContext sc = SSLContext.getInstance("TLS"); 
     sc.init(kmf.getKeyManagers(), tmf.getTrustManagers(), new SecureRandom()); 

     SSLServerSocketFactory ssf = sc.getServerSocketFactory(); 
     SSLServerSocket s = (SSLServerSocket) ssf.createServerSocket(sslPort); 
     printServerSocketInfo(s); 

     //WAIT FOR CONNECTION TODO ADD THREAD for NIO 
     SSLSocket c = (SSLSocket) s.accept(); 
     printSocketInfo(c); 

     BufferedWriter w = new BufferedWriter(new OutputStreamWriter(
      c.getOutputStream())); 
     BufferedReader r = new BufferedReader(new InputStreamReader(
      c.getInputStream())); 

     String m = "Welcome to SSL Reverse Echo Server."+ 
      " Please type in some words."; 
     w.write(m,0,m.length()); 
     w.newLine(); 
     w.flush(); 
     while ((m=r.readLine())!= null) { 
      if (m.equals(".")) break; 
      char[] a = m.toCharArray(); 
      int n = a.length; 
      for (int i=0; i<n/2; i++) { 
       char t = a[i]; 
       a[i] = a[n-1-i]; 
       a[n-i-1] = t; 
      } 
      w.write(a,0,n); 
      w.newLine(); 
      w.flush(); 
     } 
     w.close(); 
     r.close(); 
     c.close(); 
     s.close(); 
    } catch (Exception e) { 
     e.printStackTrace(); 
    } 
    } 
    private static void printSocketInfo(SSLSocket s) { 
    System.out.println("Socket class: "+s.getClass()); 
    System.out.println(" Remote address = " 
     +s.getInetAddress().toString()); 
    System.out.println(" Remote port = "+s.getPort()); 
    System.out.println(" Local socket address = " 
     +s.getLocalSocketAddress().toString()); 
    System.out.println(" Local address = " 
     +s.getLocalAddress().toString()); 
    System.out.println(" Local port = "+s.getLocalPort()); 
    System.out.println(" Need client authentication = " 
     +s.getNeedClientAuth()); 
    SSLSession ss = s.getSession(); 
    System.out.println(" Cipher suite = "+ss.getCipherSuite()); 
    System.out.println(" Protocol = "+ss.getProtocol()); 
    } 
    private static void printServerSocketInfo(SSLServerSocket s) { 
    System.out.println("Server socket class: "+s.getClass()); 
    System.out.println(" Socket address = " 
     +s.getInetAddress().toString()); 
    System.out.println(" Socket port = " 
     +s.getLocalPort()); 
    System.out.println(" Need client authentication = " 
     +s.getNeedClientAuth()); 
    System.out.println(" Want client authentication = " 
     +s.getWantClientAuth()); 
    System.out.println(" Use client mode = " 
     +s.getUseClientMode()); 
    } 
} 

CLIENT - SSLSocketClient.java

import java.io.*; 
import java.net.*; 
import javax.net.ssl.*; 

public class SSLSocketClient { 

    public static void main(String[] args) { 

    int sslPort = 9099; 

    BufferedReader in = new BufferedReader(new InputStreamReader(System.in)); 
    PrintStream out = System.out; 

    SSLSocketFactory f = (SSLSocketFactory) SSLSocketFactory.getDefault(); 

    try { 
     SSLSocket c = (SSLSocket) f.createSocket("localhost", sslPort); 
     printSocketInfo(c); 
     c.startHandshake(); 

     BufferedWriter w = new BufferedWriter(new OutputStreamWriter(c.getOutputStream())); 
     BufferedReader r = new BufferedReader(new InputStreamReader(c.getInputStream())); 

     String m = null; 
     while ((m=r.readLine())!= null) { 
      out.println(m); 
      m = in.readLine(); 
      w.write(m,0,m.length()); 
      w.newLine(); 
      w.flush(); 
     } 
     w.close(); 
     r.close(); 
     c.close(); 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } 
    } 
    private static void printSocketInfo(SSLSocket s) { 
    System.out.println("Socket class: "+s.getClass()); 
    System.out.println(" Remote address = " 
     +s.getInetAddress().toString()); 
    System.out.println(" Remote port = "+s.getPort()); 
    System.out.println(" Local socket address = " 
     +s.getLocalSocketAddress().toString()); 
    System.out.println(" Local address = " 
     +s.getLocalAddress().toString()); 
    System.out.println(" Local port = "+s.getLocalPort()); 
    System.out.println(" Need client authentication = " 
     +s.getNeedClientAuth()); 
    SSLSession ss = s.getSession(); 
    System.out.println(" Cipher suite = "+ss.getCipherSuite()); 
    System.out.println(" Protocol = "+ss.getProtocol()); 
    } 
} 

サーバ:私は次のように相互に接続するようになっているクライアントとサーバーアプリケーションを持っていますSERVERを実行し、指定されたポートでリッスンを開始しますが、CLIENTが実行されました。次のスタックトレースを取得しました。

サーバー出力

Server socket class: class sun.security.ssl.SSLServerSocketImpl 
    Socket address = 0.0.0.0/0.0.0.0 
    Socket port = 9099 
    Need client authentication = false 
    Want client authentication = false 
    Use client mode = false 
Socket class: class sun.security.ssl.SSLSocketImpl 
    Remote address = /127.0.0.1 
    Remote port = 62145 
    Local socket address = /127.0.0.1:9099 
    Local address = /127.0.0.1 
    Local port = 9099 
    Need client authentication = false 
    Cipher suite = SSL_NULL_WITH_NULL_NULL 
    Protocol = NONE 
javax.net.ssl.SSLException: Connection has been shutdown: javax.net.ssl.SSLHandshakeException: Received fatal alert: certificate_unknown 
    at sun.security.ssl.SSLSocketImpl.checkEOF(SSLSocketImpl.java:1541) 
    at sun.security.ssl.SSLSocketImpl.checkWrite(SSLSocketImpl.java:1553) 
    at sun.security.ssl.AppOutputStream.write(AppOutputStream.java:71) 
    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 java.io.BufferedWriter.flush(BufferedWriter.java:254) 
    at com.example.SSLReverseEchoer.main(SSLReverseEchoer.java:60) 
Caused by: javax.net.ssl.SSLHandshakeException: Received fatal alert: certificate_unknown 
    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:2023) 
    at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1125) 
    at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1375) 
    at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1403) 
    at sun.security.ssl.SSLSocketImpl.getSession(SSLSocketImpl.java:2267) 
    at com.example.SSLReverseEchoer.printSocketInfo(SSLReverseEchoer.java:94) 
    at com.example.SSLReverseEchoer.main(SSLReverseEchoer.java:49) 

クライアントの出力

Socket class: class sun.security.ssl.SSLSocketImpl 
    Remote address = localhost/127.0.0.1 
    Remote port = 9099 
    Local socket address = /127.0.0.1:62145 
    Local address = /127.0.0.1 
    Local port = 62145 
    Need client authentication = false 
    Cipher suite = SSL_NULL_WITH_NULL_NULL 
    Protocol = NONE 
javax.net.ssl.SSLException: Connection has been shutdown: javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target 
    at sun.security.ssl.SSLSocketImpl.checkEOF(SSLSocketImpl.java:1541) 
    at sun.security.ssl.SSLSocketImpl.checkWrite(SSLSocketImpl.java:1553) 
    at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1399) 
    at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1387) 
    at com.example.SSLSocketClient.main(SSLSocketClient.java:23) 
Caused by: javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target 
    at sun.security.ssl.Alerts.getSSLException(Alerts.java:192) 
    at sun.security.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1949) 
    at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:302) 
    at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:296) 
    at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1509) 
    at sun.security.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:216) 
    at sun.security.ssl.Handshaker.processLoop(Handshaker.java:979) 
    at sun.security.ssl.Handshaker.process_record(Handshaker.java:914) 
    at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1062) 
    at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1375) 
    at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1403) 
    at sun.security.ssl.SSLSocketImpl.getSession(SSLSocketImpl.java:2267) 
    at com.example.SSLSocketClient.printSocketInfo(SSLSocketClient.java:55) 
    at com.example.SSLSocketClient.main(SSLSocketClient.java:22) 
Caused by: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target 
    at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:387) 
    at sun.security.validator.PKIXValidator.engineValidate(PKIXValidator.java:292) 
    at sun.security.validator.Validator.validate(Validator.java:260) 
    at sun.security.ssl.X509TrustManagerImpl.validate(X509TrustManagerImpl.java:324) 
    at sun.security.ssl.X509TrustManagerImpl.checkTrusted(X509TrustManagerImpl.java:229) 
    at sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:124) 
    at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1491) 
    ... 9 more 
Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target 
    at sun.security.provider.certpath.SunCertPathBuilder.build(SunCertPathBuilder.java:141) 
    at sun.security.provider.certpath.SunCertPathBuilder.engineBuild(SunCertPathBuilder.java:126) 
    at java.security.cert.CertPathBuilder.build(CertPathBuilder.java:280) 
    at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:382) 
    ... 15 more 

は、私は次のパラメータでX509_certificate.cersslkeystore.jksを生成するためのキーストアを使用しました

ここで間違って何が起こっているかの

keytool -export -alias sslsocket -keystore sslkeystore.jks -rfc -file X509_certificate.cer 
Enter keystore password: 
Certificate stored in file <X509_certificate.cer> 

任意の提案certificate.cer sslkeystore.jks

keytool -genkey -keyalg RSA -alias sslsocket -keystore sslkeystore.jks -storepass sslkeystorepassword -validity 365 -keysize 2048 
What is your first and last name? 
    [Unknown]: Gandalf 
What is the name of your organizational unit? 
    [Unknown]: Wizardry 
What is the name of your organization? 
    [Unknown]: Arnock 
What is the name of your City or Locality? 
    [Unknown]: Minas Tirith 
What is the name of your State or Province? 
    [Unknown]: Gondor 
What is the two-letter country code for this unit? 
    [Unknown]: GD 
Is CN=Gandalf, OU=Wizardry, O=Arnock, L=Minas Tirith, ST=Gondor, C=GD correct? 
    [no]: yes 

Enter key password for <sslsocket> 
    (RETURN if same as keystore password): 

エクスポートを生成?

私がここで達成しようとしているのは、公開鍵と秘密鍵を持つソケットの非対称暗号化です。 * .jksは公開鍵を保持せず、* .cerは秘密鍵を保持しませんか?これが当てはまる場合、私は秘密鍵を使用するためにクライアントに何か追加が必要ですか、それともハンドシェイク中にクライアントに与えられますか?

ご協力いただければ幸いです。

答えて

関連する問題