4

apache.commons.net -frameworkを使用して、JavaでFTPSクライアント(FTP over SSL / TLS)を実装しました。デフォルトのポート21で明示的なセキュリティを実行するように構成されています。

ftpsClient = new FTPSClient(false);
ftpsClient.setTrustManager(getConfiguration().getCertificatesManager());
ftpsClient.connect(getConfiguration().getHostName(), getConfiguration().getPort());

サーバーにクライアント認証を適用しない限り、すべてが正常に機能します。ただし、クライアント認証を有効にする必要があるため、サーバーに認証を適用し、クライアントシステムのプロパティを構成します。

-Djavax.net.ssl.keyStore="D:/.../ftps-client-auth.keystore"
-Djavax.net.ssl.keyStorePassword="*****"
-Djavax.net.ssl.keyStoreType=JKS

私が得たものは、システムプロパティを設定しなかった場合と同じでした。

javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure
    at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Alerts.java:174)
    at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Alerts.java:136)
    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.recvAlert(SSLSocketImpl.java:1806)
    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:986)
    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1170)
    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1197)
    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1181)
    at org.apache.commons.net.ftp.FTPSClient.sslNegotiation(FTPSClient.java:265)
    at org.apache.commons.net.ftp.FTPSClient._connectAction_(FTPSClient.java:207)
    at org.apache.commons.net.SocketClient.connect(SocketClient.java:172)
    at org.apache.commons.net.SocketClient.connect(SocketClient.java:192)

サーバーログには次のように記載されています。

DEBUG: Client "<my ip address>", "SSL_accept failed: error:140890C7:SSL routines:SSL3_GET_CLIENT_CERTIFICATE:peer did not return a certificate"

正しいようです-私は-Djavax.net.debug=allを有効にしました。これは、サーバーが受け入れるCNのリストを送信するが、クライアントは空の証明書チェーンを送信することを示しています。

  • 私は何を間違えましたか?
  • プログラムで設定を行う必要がありますか?
  • 証明書または秘密鍵はSSL/TLSに特別な何かをサポートする必要がありますか?
4

1 に答える 1

5

考え出した: プログラムで . を設定する必要がありますKeyManager-Djavax.net.ssl.keyStoreフレームワークは Suns を使用しないため、システム プロパティ ( 、...) を設定するだけでは不十分SSLSocketFactoryです。

例:

ftpsClient = new FTPSClient(false);
ftpsClient.setTrustManager(TrustManagerUtils.getAcceptAllTrustManager());
KeyManager keyManager = org.apache.commons.net.util.KeyManagerUtils.createClientKeyManager(new File(keystorePath), keystorePass);
ftpsClient.setKeyManager(keyManager);
ftpsClient.connect(getConfiguration().getHostName(), getConfiguration().getPort());

Java キーストアに基づくものなど、別の Trust-Manager を選択することもできます。utils もそのための方法を提供します。TrustManagerUtils.getDefaultTrustManager(keystore)

于 2012-11-20T17:58:59.443 に答える