2016-12-05 2 views
1

java SSLソケット経由で接続するクライアントとサーバを作成しています。サーバーのみが認証されます(一方向認証)。クライアントがサーバーに接続すると、クライアントはユーザーに1行の入力を求め、サーバーに送信します。KeyManagerFactoryImplを初期化する際のクライアント/サーバプログラムのエラー

私はクライアントを実行するたびに、私は次のエラーを取得する:

Exception in thread "main" java.lang.IllegalStateException: KeyManagerFactoryImpl is not initialized 
    at sun.security.ssl.KeyManagerFactoryImpl.engineGetKeyManagers(KeyManagerFactoryImpl.java:51) 
    at javax.net.ssl.KeyManagerFactory.getKeyManagers(KeyManagerFactory.java:289) 
    at SSLClient.createSSLContext(SSLClient.java:43) 
    at SSLClient.main(SSLClient.java:50) 

私のクライアントコードは次のとおりです。

import java.io.IOException; 
import java.io.InputStream; 
import java.io.OutputStream; 
import java.net.Socket; 

import javax.net.ssl.KeyManagerFactory; 
import javax.net.ssl.SSLContext; 
import javax.net.ssl.SSLSocket; 
import javax.net.ssl.SSLSocketFactory; 

public class SSLClient { 

    public static final int PORT_NO = 9020; 
    static void doProtocol(Socket cSock) throws IOException 
    { 
     OutputStream  out = cSock.getOutputStream(); 
     InputStream  in = cSock.getInputStream(); 

     out.write("World".getBytes()); 
     out.write('!'); 

     int ch = 0; 
     while ((ch = in.read()) != '!') 
     { 
      System.out.print((char)ch); 
     } 

     System.out.println((char)ch); 
    } 
    static SSLContext createSSLContext() throws Exception 
    { 
     // set up a key manager for our local credentials 
     KeyManagerFactory mgrFact = KeyManagerFactory.getInstance("SunX509"); 
//  KeyStore clientStore = KeyStore.getInstance("PKCS12"); 

//  clientStore.load(new FileInputStream("client.p12"), "Password"); 

//  mgrFact.init(clientStore, "password"); 

     // create a context and set up a socket factory 
     SSLContext sslContext = SSLContext.getInstance("TLS"); 

     sslContext.init(mgrFact.getKeyManagers(), null, null); 

     return sslContext; 
} 

    public static void main(String[] args) throws Exception 
    { 
     SSLContext  sslContext = createSSLContext(); 
     SSLSocketFactory fact = sslContext.getSocketFactory(); 
//  SSLSocketFactory fact = (SSLSocketFactory)SSLSocketFactory.getDefault(); 
     SSLSocket  cSock = (SSLSocket)fact.createSocket("localhost", PORT_NO); 

     doProtocol(cSock); 
    } 
} 

マイServerのコードは次のとおりです。

import java.io.BufferedInputStream; 
import java.io.FileInputStream; 
import java.io.IOException; 
import java.io.InputStream; 
import java.io.OutputStream; 
import java.io.PrintStream; 
import java.net.ServerSocket; 
import java.net.Socket; 
import java.security.KeyStore; 
import java.security.Principal; 
import java.util.Date; 

import javax.net.ssl.KeyManagerFactory; 
import javax.net.ssl.SSLContext; 
import javax.net.ssl.SSLPeerUnverifiedException; 
import javax.net.ssl.SSLServerSocket; 
import javax.net.ssl.SSLServerSocketFactory; 
import javax.net.ssl.SSLSession; 
import javax.net.ssl.SSLSocket; 
import javax.net.ssl.TrustManagerFactory; 
import javax.security.auth.x500.X500Principal; 

import org.bouncycastle.cert.X509v3CertificateBuilder; 
import org.bouncycastle.crypto.tls.Certificate; 
import org.bouncycastle.jcajce.provider.asymmetric.x509.KeyFactory; 


public class SSLSocketServer { 

    public static int SERVER_PORT = 9020; 


    static boolean isEndEntity(SSLSession session) throws SSLPeerUnverifiedException 
    { 
      Principal id = session.getPeerPrincipal(); 
      if (id instanceof X500Principal) 
      { 
       X500Principal x500 = (X500Principal)id; 
       String Expireddate = x500.getName("Expireddate"); 
       String Name = x500.getName("Name"); 
       return (Name.equals("James") && Date.parse(Expireddate) > System.currentTimeMillis()); 
      } 

      return false; 
    } 


    /** 
    * Carry out the '!' protocol - server side. 
    */ 
    static void doProtocol(
     Socket sSock) 
     throws IOException 
    { 
     System.out.println("session started."); 

     InputStream in = sSock.getInputStream(); 
     OutputStream out = sSock.getOutputStream(); 
     // Send Key 

     out.write("Hello ".getBytes()); 

     int ch = 0; 
     while ((ch = in.read()) != '!') 
     { 
      out.write(ch); 
     } 

     out.write('!'); 

     sSock.close(); 
    } 
    /** 
    * Create an SSL context with identity and trust stores in place 
    */ 
    SSLContext createSSLContext() 
     throws Exception 
    { 
     // set up a key manager for our local credentials 
     KeyManagerFactory mgrFact = KeyManagerFactory.getInstance("SunX509"); 
     KeyStore serverStore = KeyStore.getInstance("JKS"); 

     serverStore.load(new FileInputStream("server.jks"), "password".toCharArray()); 

     mgrFact.init(serverStore, "password".toCharArray()); 

     // set up a trust manager so we can recognize the server 
     TrustManagerFactory trustFact = TrustManagerFactory.getInstance("SunX509"); 
     KeyStore   trustStore = KeyStore.getInstance("JKS"); 

     trustStore.load(new FileInputStream("trustStore.jks"), "trustpassword".toCharArray()); 

     trustFact.init(trustStore); 

     // create a context and set up a socket factory 
     SSLContext sslContext = SSLContext.getInstance("TLS"); 

     sslContext.init(mgrFact.getKeyManagers(), trustFact.getTrustManagers(), null); 

     return sslContext; 
    } 


    public static void main(String[] args) throws Exception 
    { 
     SSLServerSocketFactory fact = (SSLServerSocketFactory)SSLServerSocketFactory.getDefault(); 
     SSLServerSocket  sSock = (SSLServerSocket)fact.createServerSocket(SERVER_PORT); 

     SSLSocket sslSock = (SSLSocket)sSock.accept(); 
     sSock.setNeedClientAuth(false); // current ignore 

     doProtocol(sslSock); 
    } 
} 

答えて

0

あなたがする必要があります。 KeyManagerFactories初期化メソッドの1つを呼び出してください:

init(KeyStore ks, char[] password) 

または

init(ManagerFactoryParameters spec) 

KeyManagerFactory.getKeyManagers()を呼び出す前に、それ以外の場合には、観察IllegalStateExceptionをスローします。

あなたのコードは、たとえば次のように気にいらを見ることができる:

... 
final KeyStore keyStore = KeyStore.getInstance("JKS"); 
try (final InputStream is = new FileInputStream(fullPathOfKeyStore())) { 
    keyStore.load(is, JKS_PASSWORD); 
} 
final KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory 
      .getDefaultAlgorithm()); 
kmf.init(keyStore, KEY_PASSWORD); 
... 

がいっぱい例えばprogramcreek.comを参照してください。

関連する問題