0

バックグラウンド

内部ネットワークで SSL を介して相互に通信する 2 つの Java アプリケーションを作成しようとしています。これを行うには、使用する証明書の秘密鍵エントリを含むキーストアへのアクセスを SSLEngine に付与します。

   private static SSLEngine createSslEngine()
   {
      try
      {
         KeyStore ks = KeyStore.getInstance( KeyStore.getDefaultType() );
         char[] pwdArray = "changeit".toCharArray();
         ks.load( null, pwdArray );
         try ( InputStream ksIs = ServerAssociationConnector.class.getResourceAsStream( "clientkeystore" ) )
         {
            ks.load( ksIs, pwdArray  );
         }
         KeyManagerFactory kmf = KeyManagerFactory.getInstance( KeyManagerFactory.getDefaultAlgorithm() );

         kmf.init( ks, pwdArray );
         SSLContext context = SSLContext.getInstance( "TLSv1.3" );
         context.init( kmf.getKeyManagers(), null, null );

         return context.createSSLEngine();
      }
      catch ( NoSuchAlgorithmException | UnrecoverableKeyException | KeyStoreException | CertificateException | IOException | KeyManagementException exception )
      {
         throw new AssertionError( "SSLException", exception );
      }
   }

これは、ルート証明書を使用している場合は正常に機能します (ブラウザーで dubrovnik:2762 を押すと、信頼されていない証明書について文句を言いますが、それ以外の場合は機能します)。でも; 問題のドメイン (この例では dubrovnik と呼ばれます) に対してのみ、内部 CA によって署名された非ルート証明書を使用したいと考えています。

代わりにルート証明書を使用して証明書に署名し、サブジェクトの代替名に dubrovnik があると、Java は証明書の使用を拒否し、代わりにjavax.net.ssl.SSLHandshakeException: No available authentication scheme例外を生成します

ここに画像の説明を入力

私が使用しているキーストアにはこれが含まれています:

Keystore type: PKCS12
Keystore provider: SUN

Your keystore contains 2 entries

dubrovnik, 2 Nov 2020, PrivateKeyEntry,
Certificate fingerprint (SHA-256): 88:5F:53:7C:85:8E:65:01:3E:E1:E8:F0:D6:17:7A:8B:22:EF:11:DD:5F:E6:30:FE:A7:3B:F1:FA:07:C8:46:38
thecaroot, 2 Nov 2020, trustedCertEntry,
Certificate fingerprint (SHA-256): 9E:2F:86:B6:17:83:D2:26:88:42:49:E4:3F:DA:DA:19:31:11:18:F7:15:6D:16:35:C4:3E:1B:E4:F8:E6:FC:3A

証明書の作成方法

openssl と keytool を使用してローカル CA と署名付き証明書を作成してきました

openssl genrsa -des3 -out myCA.key 2048
openssl req -x509 -new -nodes -key myCA.key -sha256 -days 1825 -out myCA.pem

##create the certificate to sign
keytool -keystore clientkeystore -genkey -alias dubrovnik -dname "CN=dubrovnik" -ext san=dns:dubrovnik
##create a request to have certificate signed
keytool –certreq –keystore clientkeystore –alias dubrovnik –keyalg rsa –file dubrovnik.csr

##CREATE A FILE CALLED dubrovnik.conf as described in https://stackoverflow.com/a/47779814/2187042

##sign the request
openssl x509 -req -CA myCA.pem -CAkey myCA.key -in dubrovnik.csr -out dubrovnik.cer -days 3650 -CAcreateserial -extfile dubrovnik.conf -extensions v3_req
##import the root level certificate (just the certificate, not the private key)
keytool -import -keystore clientkeystore -file myCA.pem -alias theCARoot 
##import the signed client certificate
keytool -import -keystore clientkeystore -file dubrovnik.cer -alias dubrovnik

質問

javax.net.ssl.SSLHandshakeException: No available authentication scheme内部ネットワーク証明書 (ルート証明書ではない) を SSLEngine に受け入れさせ、例外を回避するにはどうすればよいですか?

4

1 に答える 1