SSL加密FTP连接代码从PHP/WinSCP转Node.js遇问题求助
解决basic-ftp连接FTP SSL的版本与证书匹配问题
我有一段可正常运行的PHP SSL FTP连接代码,以及WinSCP的C#连接配置示例。尝试使用basic-ftp包将其转为Node.js代码时,出现了SSL版本错误和证书域名不匹配错误,不清楚secureOptions应如何配置,恳请解决该问题。相关代码及错误信息如下:
原PHP代码
$host = 'ftp.someserver.com'; $port = 21; $pass = 'xxxx'; $user = 'username'; $connect = ftp_ssl_connect($host, $port); $login = ftp_login($connect, $user, $pass); if ($login) { ftp_pasv($connect, true); $list = ftp_mlsd($connect, "."); var_dump($list); } else { exit(error_get_last()); } ftp_close($connect);
WinSCP C#连接示例
SessionOptions sessionOptions = new SessionOptions { Protocol = Protocol.Ftp, HostName = "ftp.someserver.com", UserName = "username", Password = "xxxx", FtpSecure = FtpSecure.Explicit, TlsHostCertificateFingerprint = "dd:70:5c:67:xx:xx:xx:....", TimeoutInMilliseconds = 45000, }; sessionOptions.AddRawSettings("FtpForcePasvIp2", "1");
尝试的Node.js代码
const ftp = require("basic-ftp") const config = { host: "ftp.someserver.com", user: "username", password: "xxxx", port: 21, secure: true, } const client = new ftp.Client() // client.ftp.verbose = true try { await client.access(config) console.log(await client.list()) } catch(err) { console.log(err) } client.close()
出现的错误信息
- SSL版本错误:
SSL routines:ssl3_get_record:wrong version number:../deps/openssl/openssl/ssl/record/ssl3_record.c:332:
- 证书域名不匹配错误:
Error [ERR_TLS_CERT_ALTNAME_INVALID]: Hostname/IP does not match certificate's altnames: Host: ftp.shopdrawing.co.il. is not in the cert's altnames: DNS:cp31.box.co.il
解决方案
针对两个错误,通过配置secureOptions适配服务器环境,修改后的Node.js代码如下:
const ftp = require("basic-ftp") const config = { host: "ftp.someserver.com", user: "username", password: "xxxx", port: 21, secure: true, // 对应显式FTPS,与PHP、WinSCP配置一致 secureOptions: { // 适配服务器旧版TLS协议,解决SSL版本错误 minVersion: 'TLSv1', // 自定义证书验证逻辑:验证指纹+跳过域名匹配检查 checkServerIdentity: (host, cert) => { // 替换为WinSCP中配置的TlsHostCertificateFingerprint值 const expectedFingerprint = 'dd:70:5c:67:xx:xx:xx:....'; // 转换证书指纹格式(去除冒号并转小写) const actualFingerprint = cert.fingerprint256.replace(/:/g, '').toLowerCase(); const expected = expectedFingerprint.replace(/:/g, '').toLowerCase(); // 验证指纹是否匹配 if (actualFingerprint !== expected) { return new Error('证书指纹不匹配,连接不安全'); } // 跳过域名不匹配的检查(因为服务器证书域名与连接域名不一致) return undefined; } } } const client = new ftp.Client() // 开启verbose可以查看详细连接日志,方便调试 // client.ftp.verbose = true try { await client.access(config) console.log(await client.list()) } catch(err) { console.log(err) } client.close()
配置说明
secure: true:启用显式FTPS(Explicit),和PHP的ftp_ssl_connect、WinSCP的FtpSecure.Explicit逻辑一致,先建立普通FTP连接,再升级为SSL/TLS加密。minVersion: 'TLSv1':解决SSL版本错误,部分老旧FTP服务器仅支持TLSv1/TLSv1.1,而Node.js默认禁用了这些旧协议,需显式指定最低支持版本。checkServerIdentity:自定义证书验证逻辑,既保证证书指纹与WinSCP配置一致(避免信任未知证书),又跳过域名不匹配的检查(解决证书域名错误)。
临时测试方案(不推荐用于生产)
如果只是临时调试,可直接关闭证书验证(不安全,生产环境禁止使用):
secureOptions: { minVersion: 'TLSv1', rejectUnauthorized: false }
内容的提问来源于stack exchange,提问作者rodigy
相关产品推荐
相关产品推荐

