2017-10-11 10 views
0

を作るために証明書を.cerの使用私はすでにこの質問を見てきました:Need to do a GET&POST HTTPS Request using a .cer certificateは、HTTPSリクエスト

鉱山はかなり異なっている:

Java(バニラ、またはいずれかを使用してを使用してHTTPS要求を行うことが可能ですライブラリ)、サーバ証明書を信頼してクライアント証明書を提供する、キーストアを使用せずにplain証明書を使用していますか?

私は両方の証明書をX.509形式で使用していますが、すべての証明書をキーストアに入れたくありません。

+2

たとえば、「HttpsUrlConnection」のようなjavaを使用すると問題はありません。 'SSLContext'のために独自の' KeyManager'を作ってください。 –

+0

@mrmcwolfあなたは詳しく説明できますか?私は今、KeyManagerのドキュメントを探しています。 – lilezek

+0

@mrmcwolf Javaのドキュメントに続いて、私はこれを見つけました:保護されたコンストラクタを持つhttps://docs.oracle.com/javase/7/docs/api/javax/net/ssl/X509ExtendedKeyManager.html。私が使用できるサブクラスはありますか? – lilezek

答えて

0

本当に新しいキーストアファイルを作成したくない場合は、KeyStore APIを使用してメモリ内に作成し、証明書を直接ロードできます。

InputStream is = new FileInputStream("somecert.cer"); 
// You could get a resource as a stream instead. 

CertificateFactory cf = CertificateFactory.getInstance("X.509"); 
X509Certificate caCert = (X509Certificate)cf.generateCertificate(is); 

TrustManagerFactory tmf = TrustManagerFactory 
    .getInstance(TrustManagerFactory.getDefaultAlgorithm()); 
KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType()); 
ks.load(null); // You don't need the KeyStore instance to come from a file. 
ks.setCertificateEntry("caCert", caCert); 

tmf.init(ks); 

SSLContext sslContext = SSLContext.getInstance("TLS"); 
sslContext.init(null, tmf.getTrustManagers(), null); 

また、デフォルトのcacertsファイルを変更しないようにするには、独自のTrustManagerを実装する必要があります。しかし、TrustManagerはロードするためにキーストアを必要とするため、証明書だけをインポートする新しいキーストアファイルを作成することができます。

keytool -import -alias ca -file somecert.cer -keystore truststore.jks -storepass changeit 

次に、スニペットのようなものを使用してキーストアファイルを読み込みます。

TrustManagerFactory tmf = TrustManagerFactory 
    .getInstance(TrustManagerFactory.getDefaultAlgorithm()); 
// Using null here initialises the TMF with the default trust store. 
tmf.init((KeyStore) null); 

// Get hold of the default trust manager 
X509TrustManager defaultTm = null; 
for (TrustManager tm : tmf.getTrustManagers()) { 
    if (tm instanceof X509TrustManager) { 
     defaultTm = (X509TrustManager) tm; 
     break; 
    } 
} 

FileInputStream myKeys = new FileInputStream("truststore.jks"); 

// Do the same with your trust store this time 
// Adapt how you load the keystore to your needs 
KeyStore myTrustStore = KeyStore.getInstance(KeyStore.getDefaultType()); 
myTrustStore.load(myKeys, "password".toCharArray()); 

myKeys.close(); 

tmf = TrustManagerFactory 
    .getInstance(TrustManagerFactory.getDefaultAlgorithm()); 
tmf.init(myTrustStore); 

SSLContext sslContext = SSLContext.getInstance("TLS"); 
sslContext.init(null, tmf.getTrustManagers(), null); 
+0

あなたはこの質問を読んだことがありますか? –

+0

@ Code.IT編集後、彼はX.509証明書を直接読むスニペットを提供しました。ダウンフォートがあなたのものであればIdkですが、私が解決策をテストするとすぐにこれをupvoteするつもりです。 – lilezek

1

これは大まかな例です。 X509KeyManagerデコレータを表します。

KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()); 
kmf.init(null, null); 

X509KeyManager manager = (X509KeyManager) kmf.getKeyManagers()[0]; 
KeyManager km = new X509KeyManager() { 
    @Override 
    public String[] getClientAliases(String s, Principal[] principals) { 
     return manager.getServerAliases(s, principals); 
    } 

    @Override 
    public String chooseClientAlias(String[] strings, Principal[] principals, Socket socket) { 
     return manager.chooseClientAlias(strings, principals, socket); 
    } 

    @Override 
    public String[] getServerAliases(String s, Principal[] principals) { 
     return manager.getServerAliases(s, principals); 
    } 

    @Override 
    public String chooseServerAlias(String s, Principal[] principals, Socket socket) { 
     return manager.chooseServerAlias(s, principals, socket); 
    } 

    @Override 
    public X509Certificate[] getCertificateChain(String s) { 
     // You can use `s` to select the appropriate file 

     try { 
      File file = new File("path to certificate"); 

      try(InputStream is = new FileInputStream(file)) { 
       CertificateFactory factory = CertificateFactory.getInstance("X.509"); 
       return new X509Certificate[] { 
         (X509Certificate) factory.generateCertificate(is) 
       }; 
      } 
     } 
     catch (CertificateException| IOException e) { 
      e.printStackTrace(); 
     } 

     return null; 
    } 

    @Override 
    public PrivateKey getPrivateKey(String s) { 
     // You can use `s` to select the appropriate file 

     // load and private key from selected certificate 
     // this use for certificate authorisation 

     try { 
      File file = new File("private key file"); 
      byte buffer[] = Files.readAllBytes(file.toPath()); 

      KeySpec keySpec = new PKCS8EncodedKeySpec(buffer); 
      KeyFactory factory = KeyFactory.getInstance("RSA"); 

      return factory.generatePrivate(keySpec); 
     } 
     catch (NoSuchAlgorithmException | IOException | InvalidKeySpecException e) { 
      e.printStackTrace(); 
     } 

     return null; 
    } 
}; 

TrustManager tm = new X509TrustManager() { 
    @Override 
    public void checkClientTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException { 

    } 

    @Override 
    public void checkServerTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException { 

    } 

    @Override 
    public X509Certificate[] getAcceptedIssuers() { 
     try { 
      File file = new File("path to certificate"); 

      try(InputStream is = new FileInputStream(file)) { 
       CertificateFactory factory = CertificateFactory.getInstance("X.509"); 
       return new X509Certificate[] { 
         (X509Certificate) factory.generateCertificate(is) 
       }; 
      } 
     } 
     catch (CertificateException| IOException e) { 
      e.printStackTrace(); 
     } 

     return null; 
    } 
}; 

TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); 
tmf.init((KeyStore)null); //use java system trust certificates 

TrustManager managers[] = new TrustManager[tmf.getTrustManagers().length + 1]; 
System.arraycopy(tmf.getTrustManagers(), 0, managers, 0, tmf.getTrustManagers().length); 
managers[managers.length - 1] = tm; 

SSLContext context = SSLContext.getInstance("TLS"); 
context.init(new KeyManager[]{ km }, managers, new SecureRandom()); 

URL url = new URL("https://............/"); 
HttpsURLConnection connection = (HttpsURLConnection) url.openConnection(); 
connection.setSSLSocketFactory(connection.getSSLSocketFactory()); 

connection.connect(); 
関連する問題