You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用WS-Security调用SOAP服务时遇sslv3握手失败求助

Fixing SSLv3 Handshake Failure for WS-Secured SOAP Calls in PHP

Alright, let's tackle this issue—since you got SoapUI working perfectly, we know the service is reachable and your credentials are valid. The problem is definitely in how your PHP setup is handling the SSL handshake. Let's go through the most likely fixes step by step:

1. Stop Forcing SSLv3 (It's Obsolete!)

Your code explicitly sets CURLOPT_SSLVERSION to 3:

$client->setCurlOption(CURLOPT_SSLVERSION, 3);

SSLv3 has been deprecated for years, and almost no modern services (including government ones like the Polish PZ service you're using) support it anymore. SoapUI automatically uses modern TLS versions (TLS 1.2 or 1.3) by default, which is why it works without issues.

Quick Fix:

Either remove that line entirely (let curl negotiate the best supported version) or set it to TLS 1.2 (the minimum standard for most secure services):

// Option 1: Let curl auto-pick the best TLS version (preferred)
// $client->setCurlOption(CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1);

// Option 2: Force TLS 1.2 (safer if you confirm the server supports it)
$client->setCurlOption(CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1_2);

Note: CURL_SSLVERSION_TLSv1_2 requires PHP 5.5.19+ and cURL 7.34.0+. If your environment is older, you'll need to upgrade—old versions have known SSL vulnerabilities anyway.

2. Ensure cURL Trusts the Server's Certificate

SoapUI comes with a built-in bundle of trusted CA certificates, but PHP/cURL might not be configured to use one. Even if your client cert is correct, curl will reject the handshake if it doesn't trust the server's SSL certificate.

Fix:

Point curl to a valid CA certificate bundle:

// Path to your CA bundle (usually included with PHP/cURL, or download the official Mozilla one)
$client->setCurlOption(CURLOPT_CAINFO, '/path/to/cacert.pem');
$client->setCurlOption(CURLOPT_SSL_VERIFYPEER, true); // Keep this enabled in production!

Never disable CURLOPT_SSL_VERIFYPEER in production—it exposes you to man-in-the-middle attacks. Only turn it off temporarily for debugging if you're 100% sure the server's cert is trustworthy.

3. Verify Your Client Cert/Key Extraction

You're using a p12 file, but your code uses separate $pubKey and $privKey variables. Make sure you extracted them correctly from the p12, and they're in valid PEM format.

How to Extract Correctly (Using OpenSSL):

Run these commands in your terminal (you'll need your p12 password):

# Extract public certificate
openssl pkcs12 -in your-file.p12 -clcerts -nokeys -out cert.pem

# Extract private key (enter your p12 password when prompted)
openssl pkcs12 -in your-file.p12 -nocerts -out privkey.pem

Then load them into your script properly:

$pubKey = file_get_contents('cert.pem');
$privKey = file_get_contents('privkey.pem');

// If your private key is encrypted (it should be), pass the password when loading it:
// $objKey->loadKey($privKey, array('passphrase' => 'your-p12-password'));

Double-check that your code is stripping the BEGIN CERTIFICATE/END CERTIFICATE lines correctly for the BinarySecurityToken—your current code does this, but it's worth printing the output to ensure no extra newlines or characters are present.

4. Force Compatible Cipher Suites

Some older curl versions might not offer the cipher suites the server requires. You can explicitly set a list of modern, secure ciphers that are widely supported by government services:

$client->setCurlOption(CURLOPT_SSL_CIPHER_LIST, 'ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256');

These are strong, TLS 1.2-compatible ciphers that should work with most secure endpoints.

5. Debug the Handshake with Verbose Logging

If you're still stuck, enable verbose curl logging to see exactly where the handshake fails:

$client->setCurlOption(CURLOPT_VERBOSE, true);
// Log to a file instead of cluttering your output
$logFile = fopen('/tmp/curl-soap-debug.log', 'w');
$client->setCurlOption(CURLOPT_STDERR, $logFile);

Run your script, then check the log file. It will show which TLS versions/ciphers your client is offering, and exactly why the server rejected the handshake—this is invaluable for narrowing down the issue.


Final Tips:

  • Keep your PHP and cURL versions up to date—older versions have SSL/TLS bugs that can cause random handshake failures.
  • If you're testing locally, make sure your firewall/proxy isn't blocking TLS traffic to the service.

内容的提问来源于stack exchange,提问作者Kedor

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 04:42:19