2016-03-29 10 views
2

コードと入力SSL:400いいえ必要な証明書が

に送られた私は、SSL接続を確立しようとしていると私は、サーバーからの応答400 No required SSL certificate was sentを取得しています。私は標準的な方法で、例えばhereと記述されているようにこれをやっています。

OkHttpClient client  = new OkHttpClient(); 
    KeyStore keyStoreClient = getClientKeyStore(); 
    KeyStore keyStoreServer = getServerKeyStore(); 
    String algorithm  = ALGO_DEFAULT;//this is defined as "PKIX" 

    KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(algorithm); 
    keyManagerFactory.init(keyStoreClient, PASSWORD_SERVER.toCharArray()); 

    SSLContext sslContext = SSLContext.getInstance("TLS"); 

    TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(algorithm); 
    trustManagerFactory.init(keyStoreServer); 

    sslContext.init(keyManagerFactory.getKeyManagers(), trustManagerFactory.getTrustManagers(), new SecureRandom()); 

    client.setSslSocketFactory(sslContext.getSocketFactory()); 
    client.setConnectTimeout(32, TimeUnit.SECONDS); // connect timeout 
    client.setReadTimeout(32, TimeUnit.SECONDS); // socket timeout 

    return client; 

そして、ここでは、私がGETリクエストを送信するために使用するコードです::私は私のコードのサンプルは以下のようになりジャワ8.

を実行

public String get(String url) throws IOException 
{ 
    String callUrl = URL_LIVE.concat(url); 
    Request request = new Request.Builder() 
      .url(callUrl) 
      .build(); 
    Response response = this.client.newCall(request).execute(); 
    return response.body().string(); 
} 

私が有効になって:

System.setProperty("javax.net.debug", "ssl"); 

デバッグメッセージを表示するには、エラー/警告/アラートは表示されません。唯一のことは最後です。

main, called close() 
main, called closeInternal(true) 
main, SEND TLSv1.2 ALERT: warning, description = close_notify 
main, WRITE: TLSv1.2 Alert, length = 26 
main, called closeSocket(true) 

「異常な」ものとして扱うことができるのは唯一のものですが、それは疑いありません。

私が試した:

  • 異なるプロトコル有効/無効を。例えば、成功したソケットのためにTLSv1/TLSv1.1を強制する。それを試みるために、私はsslファクトリを特定のプロトコルを無効/有効にする別のファクトリにラップしました。
  • SSLv2Helloを無効にしますが、画像は変更されません。
  • Oracle policiesインストールする前にいくつかのスキップされたアルゴリズムに関する通知があったため、このインストールは「解決」されましたが、全体的な結果は同じです。
  • System.setProperty("sun.security.ssl.allowUnsafeRenegotiation", "true");を設定する - ラメが、また、KeyManagerFactory.getInstance()コールのためのalgorithmとしてKeyManagerFactory.getDefaultAlgorithm()を使用して
  • (明らかに「偽」だった)ログAllow unsafe renegotiation: trueに離れたメッセージからのものを変更しませんでした。それは例外Get Key failed: Given final block not properly paddedを発生させ、私が考えている限り、間違ったアルゴリズムが使用されているためです(thisを読んでください)。私のデフォルトのアルゴリズムは次のとおりです。SunX509
  • keytool -importcert -file /path/to/certificate -keystore keystore.jks -alias "Alias"で私のマシンに直接証明書を追加して、パスワードを設定してSystem.setProperty("javax.net.ssl.trustStore","/path/to/keystore.jks");を経由して私のプログラムでこれを使用した:(私はyesで証明書を信頼し確認した後keytoolにパスワードを設定)System.setProperty("javax.net.ssl.trustStorePassword","mypassword");を。 thisthisの投稿を参照してください。これでエラーは発生しませんでしたが、問題は解決されませんでした。
  • グローバル鍵ストア(JAVA_PATH/jre/lib/security/cacertsにあるもの)に証明書を追加すると、keytool -import -trustcacerts -keystore cacerts -storepass changeit -noprompt -alias Alias -file /path/to/certificatethisを参照)。インポート操作が成功したようですが、画像は変更されませんでした

また、デバッグには予告もあります:ssl: KeyMgr: choosing key: 1 (verified: OK) - 私はSSLエキスパートではないため、適切かどうかはわかりません。

残念ながら、私は完全な画像を観察することはできませんので、サーバー側のログが表示されません。

質問

何がこの400エラーの理由にすることができ、どのように私は(デバッグ/何か他のものを試してみてください)さらに進めることができますか?どんなヒントも高く評価されます。

+1

(1)キーペア、(2)自己署名証明書、(3)CSR、(4)CAによって署名されているものの、これらの操作のどれも作成していない限り、クライアント証明書はありませんJDKのトラストストアで有効に実行できます。 – EJP

+0

私はpkcs12形式のクライアント証明書を持っています。私は実際に 'keytool -importkeystore -destkeystore -srckeystore cert -srcstoretype PKCS12 -srcstorepass certPass -alias 1'で成功し、pkcs12 certをロック解除できるので有効な' certPass'を知っています。証明書+秘密鍵がそこに表示されます –

+0

問題が見つかりました。 @EJPのように、自己署名証明書です。私は今のところすべてを修正しました。 –

答えて

2

サーバーがクライアント側の証明書を要求しています。クライアントマシンに証明書(信頼できる機関によって署名された証明書)をインストールし、プログラムにそれを知らせる必要があります。

通常、サーバーには、組織のITセキュリティまたは一部のグローバルに信頼されるCAによって署名された証明書(「TLSサーバー認証」に設定されたキー目的)があります。同じソースから "TLSクライアント認証"の証明書を取得する必要があります。

WiresharkでTLSハンドシェイクをキャプチャすると、ServerHelloメッセージの後ろに「クライアント証明書要求」が表示され、長さ0の「クライアント証明書」メッセージが返されます。サーバーはこれを拒否します。

+0

私は証明書を持っています: 'keytool -importcert -file/path/here -keystore keystore.jks -alias"エイリアス "その後、私はパスワードを設定しました。私のプログラムでは、 'System.setProperty(" javax.net.ssl.trustStore "、"/path/to/jks ");および' System.setProperty( "javax.net.ssl.trustStorePassword"、 "password ");でも、私はまだ同じ問題があります。私は正しい輸入をしていますか? [ここ](http://stackoverflow.com/questions/4325263/how-to-import-a-cer-certificate-into-a-java-keystore)と[ここ](http://stackoverflow.com)から試しました。/a/5871352/2637490) –