Php “如何修复”;mysqli::real_connect():SSL操作失败;错误?

Php “如何修复”;mysqli::real_connect():SSL操作失败;错误?,php,mysql,ssl,openssl,Php,Mysql,Ssl,Openssl,环境: Ubuntu14.04,PHP5.5.9,MYSQL5.6.30 我不时会收到一个错误 mysqli::real_connect():SSL操作失败,代码为1。OpenSSL 错误消息: mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT); $this->objMySqli = mysqli_init(); mysqli_options ($this->objMySqli, MYSQLI_OPT_SSL_VERI

环境: Ubuntu14.04,PHP5.5.9,MYSQL5.6.30

我不时会收到一个错误

mysqli::real_connect():
SSL操作失败,代码为1。OpenSSL

错误消息:

mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
$this->objMySqli = mysqli_init();
mysqli_options ($this->objMySqli, MYSQLI_OPT_SSL_VERIFY_SERVER_CERT, true);

$this->objMySqli->ssl_set($this->SslKey, $this->SslCertificate, $this->SslCACertificate, null, null);

$link = $this->objMySqli->real_connect($this->Server, $this->Username, $this->Password, $this->Database, $this->Port);      

if (!$link) {
    throw new QMySqliDatabaseException("Unable to connect to Database", -1, null);
}
$link = $this->objMySqli->real_connect($this->Server, $this->Username, $this->Password, $this->Database, $this->Port);
错误:1408F10B:SSL例程:SSL3\u获取\u记录:版本号错误

Front/nginx位于一台服务器上,mysql位于另一台服务器上

错误不是连续的,它是随机发生的,我在错误日志中找到了这些错误消息,所以我无法真正进行完全调试

示例:

mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
$this->objMySqli = mysqli_init();
mysqli_options ($this->objMySqli, MYSQLI_OPT_SSL_VERIFY_SERVER_CERT, true);

$this->objMySqli->ssl_set($this->SslKey, $this->SslCertificate, $this->SslCACertificate, null, null);

$link = $this->objMySqli->real_connect($this->Server, $this->Username, $this->Password, $this->Database, $this->Port);      

if (!$link) {
    throw new QMySqliDatabaseException("Unable to connect to Database", -1, null);
}
$link = $this->objMySqli->real_connect($this->Server, $this->Username, $this->Password, $this->Database, $this->Port);
SSL密码:

mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
$this->objMySqli = mysqli_init();
mysqli_options ($this->objMySqli, MYSQLI_OPT_SSL_VERIFY_SERVER_CERT, true);

$this->objMySqli->ssl_set($this->SslKey, $this->SslCertificate, $this->SslCACertificate, null, null);

$link = $this->objMySqli->real_connect($this->Server, $this->Username, $this->Password, $this->Database, $this->Port);      

if (!$link) {
    throw new QMySqliDatabaseException("Unable to connect to Database", -1, null);
}
$link = $this->objMySqli->real_connect($this->Server, $this->Username, $this->Password, $this->Database, $this->Port);

这一行失败:

mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
$this->objMySqli = mysqli_init();
mysqli_options ($this->objMySqli, MYSQLI_OPT_SSL_VERIFY_SERVER_CERT, true);

$this->objMySqli->ssl_set($this->SslKey, $this->SslCertificate, $this->SslCACertificate, null, null);

$link = $this->objMySqli->real_connect($this->Server, $this->Username, $this->Password, $this->Database, $this->Port);      

if (!$link) {
    throw new QMySqliDatabaseException("Unable to connect to Database", -1, null);
}
$link = $this->objMySqli->real_connect($this->Server, $this->Username, $this->Password, $this->Database, $this->Port);

mysql版本5.6.30有问题,
我已经更新到5.6.32,现在这个错误不再发生。

升级并没有解决我的问题,但我找到了一个新的解决方案

TLDR将您的PKCS#8格式密钥转换为PKCS#1格式密钥

openssl rsa -in example.com.server.key.pem -out example.com.server.key.pkcs1.pem
我遇到了这些错误:

本质上,如果您的私钥是PKCS#8格式而不是PKCS#1格式,MySQL将无法“找到”私钥

很多堆栈溢出的答案都说重命名页眉和页脚以在页眉和页脚中包含RSA,如下所示:

From(PKCS#8格式)

To(PKCS#1格式)

但是,这不会更改页眉和页脚之间的私钥数据。当使用修改过的页眉和页脚的PKCS#8格式键时,MySQL启动时没有发生错误,但当我尝试连接mysqli时,我得到了

error:1408F10B:SSL routines:SSL3_GET_RECORD:wrong version number
通过将我的私钥转换为PKCS#1格式,密钥工作正常,我可以很好地连接:

openssl rsa -in example.com.server.key.pem -out example.com.server.key.pkcs1.pem
请注意,更新的OpenSSL版本,至少1.0.2j(我使用的)在使用时输出PKCS#8密钥

openssl req -config "openssl.cnf" \
-keyout "private/example.com.server.key.pem" -new -sha256 \
-days 3652 -nodes -out "csr/example.com.server.csr.pem"
但是使用不同的选项可能会输出PKCS#1密钥(可能是
-newkey rsa:2048
,我还没有测试过)。这就解释了为什么只有一些人在使用openssl生成的私钥时会遇到这种情况


我在MySQL 5.6.17和5.7.14中遇到了这个问题,因此这些错误似乎没有得到修复。

您是否允许在服务器上使用SSL2和SSL3密码?服务器是否允许SSL2?您使用的是PDO还是直接mysqli::real_connect()?如果使用PDO,尝试使用直接调用,它会给出更多有用的错误…@MarcoS-添加了我的script@IsmaelMiguel-添加屏幕截图您是否因太多连接故障而被阻止?看见