Java搭建的FTPS服务器无法通过FileZilla连接的问题求助
解决Java FTPS服务器与FileZilla连接的"Empty client certificate chain"问题
近期搭建Java FTPS服务器时,非SSL的FTP可正常运行,但通过FileZilla连接时提示**"Certificate is bad (42)"**,Java日志显示SSL握手失败,根因为Empty client certificate chain。以下是已执行的操作及解决方案:
已执行操作
1. 生成密钥库文件
keytool -genkey -alias mykeystore -keyalg RSA -keystore keystore.jks -keysize 2048
2. PowerShell生成并导出自签名证书
$certificate = New-SelfSignedCertificate -Type Custom -KeySpec Signature -Subject "CN=MyRootCA" -KeyExportPolicy Exportable -HashAlgorithm sha256 -KeyLength 2048 -CertStoreLocation "C:\Users\myuser" -KeyUsageProperty Sign -KeyUsage CertSign $certificate | Export-Certificate -FilePath "C:\Users\myuser\MyLocalCertificate.crt"
3. 创建信任库
keytool -import -alias myTruststore "C:\Users\myuser\myTruststore.jks" -file "C:\Users\myuser\MyLocalCertificate.crt"
4. Java FTPS服务器代码
FtpServerFactory serverFactory = new FtpServerFactory(); ConnectionConfigFactory factory = new ConnectionConfigFactory(); serverFactory.setConnectionConfig(factory.createConnectionConfig()); ListenerFactory listenerFactory = new ListenerFactory(); listenerFactory.setPort(port); SslConfigurationFactory ssl = new SslConfigurationFactory(); ssl.setKeystoreFile(new File("hostkey/keystore.jks")); ssl.setKeystorePassword("xxx"); ssl.setClientAuthentication("yes"); ssl.setTruststoreFile(new File("hostkey/myTruststore.jks")); ssl.setTruststorePassword("xxx"); listenerFactory.setSslConfiguration(ssl.createSslConfiguration()); listenerFactory.setImplicitSsl(true); serverFactory.addListener("default", listenerFactory.createListener()); listenerFactory.setDataConnectionConfiguration( new DataConnectionConfigurationFactory().createDataConnectionConfiguration()); PropertiesUserManagerFactory userManagerFactory = new PropertiesUserManagerFactory(); UserManager um = userManagerFactory.createUserManager(); // 数据库用户查询及根目录配置代码 FtpServer server = serverFactory.createServer(); server.start();
关键错误日志
javax.net.ssl.SSLHandshakeException: SSL handshake failed. Caused by: javax.net.ssl.SSLHandshakeException: Empty client certificate chain
解决方案
一、服务器端配置调整
调整客户端认证策略
当前代码设置ssl.setClientAuthentication("yes"),强制要求客户端提供证书。若不需要客户端证书认证,可改为:ssl.setClientAuthentication("no"); // 仅服务器认证 // 或 ssl.setClientAuthentication("want"); // 可选客户端认证若确实需要客户端证书认证,需确保信任库包含客户端证书的签发CA。
验证密钥库完整性
执行命令检查密钥库是否包含完整证书链:keytool -list -v -keystore keystore.jks确认证书链长度≥1,且证书信息与生成时一致。
二、FileZilla客户端配置
信任服务器根证书
- 打开FileZilla →
编辑→设置→SSL/TLS设置→信任的CA证书 - 点击
导入,选择之前生成的MyLocalCertificate.crt添加到信任列表
- 打开FileZilla →
配置客户端证书(若服务器强制要求)
- 生成由根CA签发的客户端证书,导出为PKCS#12格式(.pfx文件)
- 在FileZilla的
SSL/TLS设置→客户端证书中,选择该.pfx文件并输入证书密码
连接参数匹配
- 连接类型选择
FTPS - FTP over implicit TLS/SSL(与服务器setImplicitSsl(true)对应) - 端口使用服务器配置的端口(隐式FTPS默认端口为990)
- 连接类型选择
三、核心问题排查
Empty client certificate chain报错的核心原因:
- 服务器强制要求客户端证书,但客户端未配置
- 客户端证书未导入服务器信任库
- 客户端证书格式不符合要求(需PKCS#12格式)
内容的提问来源于stack exchange,提问作者FrenchCornichon
相关产品推荐
相关产品推荐

