web-dev-qa-db-ja.com

警告:適切な証明書が見つかりません-クライアント認証なしで続行します

チームHTTPSを使用して相互ハンドシェイクを完了しようとすると、次の問題が発生します

main, READ: TLSv1.2 Handshake, length = 30
*** CertificateRequest
Cert Types: RSA, DSS, ECDSA
Supported Signature Algorithms: SHA1withRSA, SHA1withDSA, SHA1withECDSA, SHA256withRSA, Unknown (hash:0x4, signature:0x2), SHA256withECDSA, SHA384withRSA, Unknown (hash:0x5, signature:0x2), SHA384withECDSA
Cert Authorities:
<Empty>
main, READ: TLSv1.2 Handshake, length = 4
*** ServerHelloDone
Warning: no suitable certificate found - continuing without client authentication
*** Certificate chain
<Empty>

私のJavaクラスは次のとおりです

public class ClientCustomSSL {

    @SuppressWarnings("deprecation")
    public final static void main(String[] args) throws Exception {
        // Trust own CA and all self-signed certs
        final String CLIENT_KEYSTORE = "yourkeystore.jks";
        final String CLIENT_TRUSTSTORE = "catruststore.jks";
        final char[] KEYPASS_AND_STOREPASS_VALUE = "Hello1".toCharArray();


        System.setProperty("https.protocols", "TLSv1");

        //SSLContext sslcontext = SSLContexts.custom().loadKeyMaterial(keystore, keyPassword)(YK,"Hello1".toCharArray(),"Hello1".toCharArray()).loadTrustMaterial(CA, "Hello1".toCharArray(), (TrustStrategy) new TrustSelfSignedStrategy()).build();

        KeyStore clientTrustStore = getStore(CLIENT_TRUSTSTORE, KEYPASS_AND_STOREPASS_VALUE);
        KeyStore clientKeyStore = getStore(CLIENT_KEYSTORE, KEYPASS_AND_STOREPASS_VALUE);  


        SSLContext sslContext = SSLContexts.custom().loadKeyMaterial(clientKeyStore, "Hello1".toCharArray()).loadTrustMaterial(clientTrustStore,(TrustStrategy) new TrustSelfSignedStrategy()).build();
       CloseableHttpClient httpclient = HttpClients.custom().setSSLContext(sslContext).build();

        System.out.println("SSLCONETXT   **** " + sslContext.getProvider());
        try {

            HttpGet httpget = new HttpGet("https://myserver:10220");

            CloseableHttpResponse response = httpclient.execute(httpget);

            try {
                System.out.println("Inside TRY blcok"); 
                HttpEntity entity = response.getEntity();
                System.out.println("----------------------------------------");
                System.out.println(response.getStatusLine());
                EntityUtils.consume(entity);

            } catch (Exception e) {
                e.getMessage();
                e.printStackTrace();
            }
            finally {
                response.close();
            }
        } finally {
            httpclient.close();
        }
    }


    public static KeyStore getStore(final String storeFileName, final char[] password) throws KeyStoreException, IOException, CertificateException, NoSuchAlgorithmException 
    {
        final String Java_KEYSTORE = "jks";
        final KeyStore store = KeyStore.getInstance(Java_KEYSTORE);
        URL url = ClientCustomSSL.class.getClassLoader().getResource(storeFileName);
        String workingDir = System.getProperty("user.dir");
        System.out.println("Current working directory : " + workingDir);

        System.out.println("Value of URL *** " + url);
        InputStream inputStream = url.openStream();
        try {
            store.load(inputStream, password);
} finally {
    inputStream.close();
}

return store;
}

}

私はjarファイルを準備して、これをUNIXボックスからテストしています

次のコマンドを使用Java -Djavax.net.debug = ssl -cp snSSLclientTrustWithStoreCCC.jar cassandra.cass.ClientCustomSSL

私は投稿に従いました なぜしないJava SSLハンドシェイク中にクライアント証明書を送信しますか? また、Brunoが述べたすべてのステップを完了しました。

ここで何が欠けているのかわかりません。助けていただければ幸いです

10
P.K
  1. クライアントは、CertificateRequestメッセージで言及されている署名者のいずれかによって直接または間接的に署名された証明書をキーストアで見つけることができませんでした。
  2. その理由は、サーバーがそのメッセージで信頼できる署名者を指定しなかったためです。
  3. これは、サーバーのトラストストアが空であることを意味します。
7
user207421

これは実際にはTLS 1.0仕様とTLS 1.1/1.2が異なる領域です。

特に、TLS 1.1の セクション7.4.4(証明書リクエスト)に以下が追加されました

Certificate_authoritiesリストが空の場合、クライアントは、反対の外部配置がない限り、適切なClientCertificateTypeの証明書を送信できます(MAY)。

したがって、空の認証局は、クライアントがサーバーに証明書を自由に送信できることを意味します。これは、サーバーの内部ルールによって受け入れられる場合と受け入れられない場合があります。

1
peak

私の場合、問題は、鍵ストアをロードするときにパスワードとしてnullを渡していたことでした。

KeyStore keyStore = KeyStore.getInstance("PKCS12")
InputStream inputStream = new FileInputStream('/path/to/mykeystore.p12')

try {
    keyStore.load(inputStream, null); // <-- PROBLEM HERE!
}
finally {
    inputStream.close();
}

これはエラーメッセージを生成しませんでしたが、クライアントのキーと証明書のロードに静かに失敗しました

解決策はパスワードを渡すことでした:

keyStore.load(inputStream as InputStream, 'mypassword'.toCharArray());
0
Sam