Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/379.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何使用apache.commons.net.ftps配置客户端身份验证?_Java_Ssl_Apache Commons Net_Ftps_Authentication - Fatal编程技术网

Java 如何使用apache.commons.net.ftps配置客户端身份验证?

Java 如何使用apache.commons.net.ftps配置客户端身份验证?,java,ssl,apache-commons-net,ftps,authentication,Java,Ssl,Apache Commons Net,Ftps,Authentication,我使用apache.commons.net-framework在java中实现了一个FTPS客户端(FTP over SSL/TLS)。 它被配置为在默认端口21上执行显式安全性 ftpsClient = new FTPSClient(false); ftpsClient.setTrustManager(getConfiguration().getCertificatesManager()); ftpsClient.connect(getConfiguration().getHostName()

我使用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)
我得到的结果与未设置系统属性的情况相同:

-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"
调试:客户端“”“SSL\u接受失败:错误:140890C7:SSL例程:SSL3\u获取\u客户端\u证书:对等方未返回证书”
似乎是正确的-I enabled-Djavax.net.debug=all,这表明服务器发送一个它接受的CNs列表,而客户端发送一个空证书链

  • 我做错了什么?
  • 我需要按程序进行一些配置吗?
  • 证书或私钥是否需要支持SSL/TLS的任何特殊功能?

解决了这个问题:您需要以编程方式设置
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密钥库的信任管理器。UTIL也为此提供了一种方法:

这个getConfiguration()是什么??getConfiguration??你在哪里找到的?我更新了这个例子。请看一下TrustManagerUtils以创建一个实例。您是如何设置服务器的?设置强制SSL和客户端身份验证的服务器时遇到问题。关于您使用什么设置它有什么帮助吗?@trynacode一位同事使用客户端身份验证设置了一个vsftp服务器。不幸的是,我不知道他使用的设置。我会调查的,然后安迪。谢谢你的回复!