PHP PDO SSL MySQL 连接失败

发布于 2025-01-08 12:47:15 字数 394 浏览 1 评论 0 原文

我正在尝试开发一个使用 SSL 连接到 MySQL 服务器的 PHP 应用程序。 我尝试使用 mysql_connect 并且工作正常,但使用 PDO 则不行。当我尝试连接时出现以下错误:

PDO::__construct():此流不支持 SSL/加密

看起来很奇怪的是,如果我调整证书路径(指向不存在的文件),我会得到相同的错误!

我在 Debian Squeeze 上使用 php 5.3.10,安装了以下软件包:

php5-cgi 
php5-cli
php5-common
php5-fpm
php5-gd
php5-mcrypt
php5-mysql
php5-suhosin

知道吗?谢谢

I'm trying to develop a PHP application which connects to a MySQL server using SSL.
I tried using mysql_connect and works fine, but with PDO it does not. When I try to connect I get the following error:

PDO::__construct(): this stream does not support SSL/crypto

What looks strange is that if I tweak cert paths (to point to non existent files) I get the same error!

I'm using php 5.3.10 on Debian Squeeze, the following packages are installed:

php5-cgi 
php5-cli
php5-common
php5-fpm
php5-gd
php5-mcrypt
php5-mysql
php5-suhosin

Any idea? thanks

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

眼中杀气 2025-01-15 12:47:15

您需要删除 php-mysql 并安装 php-mysqlnd。在 Centos 上:

sudo yum remove php-mysql
sudo yum install php-mysqlnd
sudo yum reboot

Ubuntu/Debian

sudo apt-get remove php5-mysql
sudo apt-get install php5-mysqlnd
sudo reboot

mysqli 程序:

$con=mysqli_init();
if (!$con)
  {
  die("mysqli_init failed");
  }

mysqli_ssl_set($con,'/ssl/client-key.pem','/ssl/client-cert.pem', '/ssl/ca.pem',NULL,NULL);

if (!mysqli_real_connect($con,'xx.xxx.xxx.xxx', 'user', 'pass' ,'dbname'))
  {
  die("Connect Error: " . mysqli_connect_error());
  }

mysqli_close($con);
?>

PDO

$ssl = array(
                PDO::MYSQL_ATTR_SSL_KEY    =>'/ssl/client-key.pem',
                PDO::MYSQL_ATTR_SSL_CERT=>'/ssl/client-cert.pem',
                PDO::MYSQL_ATTR_SSL_CA    =>'/ssl/ca.pem'
        );
        try {
                $dbl = new PDO("mysql:host=$host;dbname=$database", $user, $password, $ssl);
                $dbl->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
        } catch(PDOException $e) {
echo $e->getMessage();
die;
        }

您的证书路径必须正确。在 SSL 中尝试此操作以确保文件存在:

if(file_exists('/ssl/client-key.pem') && file_exists('/ssl/client-cert.pem') && file_exists('/ssl/ca.pem')) echo 'file exists';

远程主机(数据库服务器)也必须启用 SSL。运行查询

SHOW VARIABLES LIKE '%ssl%';

输出:

+---------------+----------------------+
| Variable_name | Value                |
+---------------+----------------------+
| have_openssl  | YES                  |
| have_ssl      | YES                  |
| ssl_ca        | /ssl/ca.pem          |
| ssl_capath    |                      |
| ssl_cert      | /ssl/server-cert.pem |
| ssl_cipher    | DHE-RSA-AES256-SHA   |
| ssl_key       | /ssl/server-key.pem  |
+---------------+----------------------+

如果它被禁用,它将不起作用。您的 /etc/my.cnf (或 my.cnf 所在位置)必须包含:

ssl-ca=/ssl/ca.pem
ssl-cert=/ssl/server-cert.pem
ssl-key=/ssl/server-key.pem
ssl-cipher=DHE-RSA-AES256-SHA

用于生成密钥的 MySQL 资源:http://dev.mysql.com/doc/refman/5.0/en/creating-ssl-files-using-openssl.html

最后,DHE 密码不再被认为是安全的。密码不断被破解,因此您必须找出当今哪些密码被认为是安全的。

You need php-mysql removed and php-mysqlnd installed. On Centos:

sudo yum remove php-mysql
sudo yum install php-mysqlnd
sudo yum reboot

Ubuntu/Debian

sudo apt-get remove php5-mysql
sudo apt-get install php5-mysqlnd
sudo reboot

mysqli procedural:

$con=mysqli_init();
if (!$con)
  {
  die("mysqli_init failed");
  }

mysqli_ssl_set($con,'/ssl/client-key.pem','/ssl/client-cert.pem', '/ssl/ca.pem',NULL,NULL);

if (!mysqli_real_connect($con,'xx.xxx.xxx.xxx', 'user', 'pass' ,'dbname'))
  {
  die("Connect Error: " . mysqli_connect_error());
  }

mysqli_close($con);
?>

PDO

$ssl = array(
                PDO::MYSQL_ATTR_SSL_KEY    =>'/ssl/client-key.pem',
                PDO::MYSQL_ATTR_SSL_CERT=>'/ssl/client-cert.pem',
                PDO::MYSQL_ATTR_SSL_CA    =>'/ssl/ca.pem'
        );
        try {
                $dbl = new PDO("mysql:host=$host;dbname=$database", $user, $password, $ssl);
                $dbl->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
        } catch(PDOException $e) {
echo $e->getMessage();
die;
        }

Your certs paths must be correct. Try this in your SSL to ensure the files are there:

if(file_exists('/ssl/client-key.pem') && file_exists('/ssl/client-cert.pem') && file_exists('/ssl/ca.pem')) echo 'file exists';

The remote host (database server) must also have SSL enabled. Run the query

SHOW VARIABLES LIKE '%ssl%';

OUTPUT:

+---------------+----------------------+
| Variable_name | Value                |
+---------------+----------------------+
| have_openssl  | YES                  |
| have_ssl      | YES                  |
| ssl_ca        | /ssl/ca.pem          |
| ssl_capath    |                      |
| ssl_cert      | /ssl/server-cert.pem |
| ssl_cipher    | DHE-RSA-AES256-SHA   |
| ssl_key       | /ssl/server-key.pem  |
+---------------+----------------------+

If it's disabled, it will not work. Your /etc/my.cnf (or where your my.cnf is located) must contain:

ssl-ca=/ssl/ca.pem
ssl-cert=/ssl/server-cert.pem
ssl-key=/ssl/server-key.pem
ssl-cipher=DHE-RSA-AES256-SHA

MySQL Resource to generate keys: http://dev.mysql.com/doc/refman/5.0/en/creating-ssl-files-using-openssl.html

Lastly, the DHE cipher is not considered safe anymore. Ciphers are continually being broke, so you'll have to find out which are considered secure today.

Bonjour°[大白 2025-01-15 12:47:15

您的模块列表不包括 openssl

您可以使用 php -m 检查已编译的模块。您可以通过运行 php -a 然后执行 var_dump(get_loaded_extensions()); 来检查运行时加载的所有模块,

您将需要将其编译或加载为为了使用 SSL 连接的扩展。

如果扩展存在于磁盘上(检查您的 php 扩展目录 - 位于 php.ini 中),那么还要检查您的 php.ini 中的行 extension=php_openssl。 so 并确保它没有被注释掉。

Your list of modules doesn't include include openssl

You can check the compiled in modules with php -m. And you can check all modules loaded at runtime by running php -a then executing var_dump(get_loaded_extensions());

You will need this to be either compiled in, or loaded as an extension in order to use SSL connectivity.

If the extension exists on disk (check your php extensions directory - location in php.ini) then also check your php.ini for the line extension=php_openssl.so and make sure it is not commented out.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文