【问题标题】:How to configure client authentication with apache.commons.net.ftps?如何使用 apache.commons.net.ftps 配置客户端身份验证?
【发布时间】:2012-11-20 10:16:58
【问题描述】:

我使用 apache.commons.net-框架在 java 中实现了一个 FTPS 客户端(基于 SSL/TLS 的 FTP)。 它被配置为在默认端口 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 的任何特殊功能?

【问题讨论】:

  • 您是如何设置服务器的?在设置强制执行 SSL 和客户端身份验证的服务器时遇到问题。关于你用来设置它的任何帮助?
  • @trynacode 一位同事设置了一个带有客户端身份验证的 vsftp 服务器。不幸的是,我不知道他使用的设置。
  • 我会看看安迪。感谢您的回复!

标签: java ssl apache-commons-net ftps authentication


【解决方案1】:

想通了:您需要以编程方式设置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());

您可能想要选择不同的 Trust-Manager,例如一种基于 Java 密钥库的。实用程序也为此提供了一种方法:TrustManagerUtils.getDefaultTrustManager(keystore)

【讨论】:

  • 这是什么 getConfiguration()。 ??
  • getConfiguration ??你在哪里找到的?
  • 我更新了示例。看看 TrustManagerUtils 创建一个实例。
猜你喜欢
  • 2015-06-20
  • 1970-01-01
  • 2018-09-16
  • 2019-01-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-02-04
相关资源
最近更新 更多