PHP Warning: fgets() SSL操作失败问题求助(Horde_Imap_Client)
PHP SSL Decrypt Error with Horde IMAP Client (fgets(): bad decrypt)
Let's break down this issue and walk through targeted fixes—since you mentioned another identical instance works perfectly, the problem is almost certainly tied to a specific difference between your two setups.
First, let's recap your error and code context:
Error Log
[Thu Jan 25 10:39:42.689306 2018] [:error] [pid 21084] PHP Warning: fgets(): SSL operation failed with code 1. OpenSSL Error messages: error:06065064:digital envelope routines:EVP_DecryptFinal_ex:bad decrypt error:06065064:digital envelope routines:EVP_DecryptFinal_ex:bad decrypt error:06065064:digital envelope routines:EVP_DecryptFinal_ex:bad decrypt error:06065064:digital envelope routines:EVP_DecryptFinal_ex:bad decrypt in ../vendor/pear-pear.horde.org/Horde_Imap_Client/Horde/Imap/Client/Socket/Connection/Socket.php on line 156
Affected Code Snippet (line 156 is the fgets loop)
public function read($size = null) { $got_data = false; $literal_len = null; $token = new Horde_Imap_Client_Tokenize(); do { if (feof($this->_stream)) { $this->close(); $this->_params['debug']->info( 'ERROR: Server closed the connection.' ); throw new Horde_Imap_Client_Exception( Horde_Imap_Client_Translation::r("Mail server closed the connection unexpectedly."), Horde_Imap_Client_Exception::DISCONNECT ); } if (is_null($literal_len)) { $buffer = ''; while (($in = fgets($this->_stream)) !== false) { // <-- Error occurs here $got_data = true; if (substr($in, -1) === "\n") { $in = rtrim($in); $this->_params['debug']->server($buffer . $in); $token->add($in); break; } $buffer .= $in; $token->add($in); } /* Check for literal data. */ if (is_null($len = $token->getLiteralLength())) { break; } // Skip 0-length literal data. if ($len['length']) { $binary = $len['binary']; $literal_len = $len['length']; } continue; } $old_len = $literal_len; while (($literal_len > 0) && !feof($this->_stream)) { $in = fread($this->_stream, min($literal_len, 8192)); /* Only store in stream if this is something more than a * nominal number of bytes. */ if ($old_len > 256) { $token->addLiteralStream($in); } else { $token->add($in); } if (!empty($this->_params['debugliteral'])) { $this->_params['debug']->raw($in); } $got_data = true; $literal_len -= strlen($in); } $literal_len = null; if (empty($this->_params['debugliteral'])) { $this->_params['debug']->server('[' . ($binary ? 'BINARY' : 'LITERAL') . ' DATA: ' . $old_len . ' bytes]'); } } while (true); if (!$got_data) { $this->_params['debug']->info('ERROR: read/timeout error.'); throw new Horde_Imap_Client_Exception( Horde_Imap_Client_Translation::r("Error when communicating with the mail server."), Horde_Imap_Client_Exception::SERVER_READERROR ); } return $token; }
Troubleshooting Steps (focused on instance differences)
Since one setup works, we can rule out general Horde/PHP bugs. Let's start with the most likely culprits:
1. Verify SSL Certificate Trust & CA Configuration
- Compare PHP OpenSSL settings: Check
php.inifor both instances, specificallyopenssl.cafileandopenssl.capath. The failing instance might be missing a valid CA certificate bundle (likecacert.pem) that the working instance uses. Confirm withphp -i | grep -A 5 OpenSSLon both servers. - Temporary test with disabled SSL verification: To rule out certificate trust issues, add these options to your Horde IMAP config (don't leave this enabled in production):
If this fixes the error, your server doesn't trust the IMAP server's certificate—either add the certificate to your CA bundle or fix the server's certificate chain.$imap_config = array( 'hostspec' => 'your-imap-server.com', 'port' => 993, 'secure' => 'ssl', 'ssl' => array( 'verify_peer' => false, 'verify_peer_name' => false ), // ... other config (username, password) );
2. Check the IMAP Server's SSL Setup
- Run an OpenSSL test: On the failing server, execute
openssl s_client -connect your-imap-host:993and look for:verify return:1: Certificate is trusted.verify return:20/21: Missing intermediate certificate or invalid hostname.
Compare this output to the working instance's IMAP server test—errors here are a clear root cause.
3. Ensure PHP/OpenSSL Version Consistency
- Compare versions: Run
php -vandphp -i | grep OpenSSLon both instances. If versions differ, the failing instance might have compatibility issues with the IMAP server's encryption suite. Match the working instance's versions to test.
4. Sync Horde Library Versions
- Check Horde_Imap_Client version: Look in
vendor/pear-pear.horde.org/Horde_Imap_Client/Horde/Imap/Client/Version.phpfor both instances. If versions differ, the failing instance might have a bug or incompatible change. Sync the library to match the working setup.
5. Inspect Stream Context Differences
- Check Horde's stream settings: Horde creates an SSL stream for IMAP connections. If the failing instance has custom stream context options (like restricted ciphers), this could cause decrypt errors. Ensure any
stream_context_createSSL parameters match the working instance.
Final Notes
Start with the simplest checks first: SSL certificate trust and PHP/OpenSSL versions. These are the most common culprits when identical setups behave differently.
内容的提问来源于stack exchange,提问作者Neo Morina
相关产品推荐
相关产品推荐

