Stripe TLS 1.2升级异常:网站已启用TLS1.2但支付仍显示TLS1.0
这种情况确实挺让人挠头的——明明网站整体已经通过TLS 1.2验证,主机商也确认配置没问题,但Stripe那边却一直提示支付请求走的是TLS 1.0。结合PHP集成Stripe的场景,大概率是下面这几个环节出了疏漏:
PHP请求的SSL配置被硬编码成了TLS 1.0
Stripe的PHP SDK底层依赖cURL或者PHP流处理发起请求,如果你的代码或者服务器的php.ini里,手动指定了固定的TLS版本为1.0,那不管网站全局配置如何,支付请求都会单独走旧协议。
排查方向:- 检查代码中有没有类似
curl_setopt($ch, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1_0)的配置,有的话改成CURL_SSLVERSION_TLSv1_2;更推荐的做法是不指定固定版本,让cURL自动协商最高可用的TLS版本(可以设置为CURL_SSLVERSION_TLSv1_0 | CURL_SSLVERSION_TLSv1_1 | CURL_SSLVERSION_TLSv1_2)。 - 查看php.ini中的
curl.cainfo和openssl.cafile是否正确配置了CA证书,这也会影响SSL握手的正常协商。
- 检查代码中有没有类似
使用的Stripe PHP SDK版本过于老旧
Stripe早在多年前就强制要求所有API请求必须使用TLS 1.2及以上版本,但旧版SDK可能还在硬编码使用TLS 1.0。尤其是v6.0.0之前的Stripe PHP SDK,默认可能不支持TLS 1.2。
解决办法:立刻升级到最新版SDK。如果用Composer管理依赖,执行composer update stripe/stripe-php即可,升级后确认版本至少在v6.0.0以上。PHP依赖的OpenSSL版本不支持TLS 1.2
即使Web服务器(Apache/Nginx)配置了TLS 1.2,如果PHP使用的OpenSSL库版本过低,也无法发起TLS 1.2的请求——TLS 1.2需要OpenSSL 1.0.1c及以上版本支持。
检查方式:在PHP代码中执行echo OPENSSL_VERSION_TEXT;,输出的版本号如果低于1.0.1c,就得联系Hostmonster升级服务器的OpenSSL版本。服务器出站请求被中间代理劫持
有些主机商的服务器内部会用代理处理出站请求,如果这个代理的SSL配置还是TLS 1.0,那即使你的代码和Web服务器都没问题,最终发往Stripe的请求还是会走旧协议。这种情况只能联系Hostmonster的技术支持,确认他们的出站请求SSL配置是否支持TLS 1.2。
快速测试方法
你可以写个简单的PHP脚本,直接测试向Stripe发起请求时使用的TLS版本:
<?php $ch = curl_init('https://api.stripe.com/v1/charges'); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_VERBOSE, true); $verboseLog = fopen('php://temp', 'w+'); curl_setopt($ch, CURLOPT_STDERR, $verboseLog); $response = curl_exec($ch); rewind($verboseLog); $logContent = stream_get_contents($verboseLog); echo "请求日志:\n" . $logContent . "\n"; curl_close($ch); ?>
运行这个脚本后,日志里会显示类似SSL connection using TLSv1.2的内容,如果显示的是TLSv1.0,那就能直接定位到是PHP/cURL的配置问题;如果是TLSv1.2,那可能是Stripe后台的缓存或者误判,建议联系Stripe支持团队确认。
内容的提问来源于stack exchange,提问作者Jonathan Safa

