phpsql-serverodbcdriversqlsrv

[MS][ODBC Driver 18 for SQL Server][error:1416F086:SSL routines:tls_process_server_certificate:certificate verify failed:self signed certificate]


I am connecting to SQL Server with sqlsrv using PHP 8.0 on Centos7 with PLESK Onyx

When trying to connect got error:

Array
(
    [0] => Array
        (
            [0] => 08001
            [SQLSTATE] => 08001
            [1] => -1
            [code] => -1
            [2] => [Microsoft][ODBC Driver 18 for SQL Server]SSL Provider: [error:1416F086:SSL routines:tls_process_server_certificate:certificate verify failed:self signed certificate]
            [message] => [Microsoft][ODBC Driver 18 for SQL Server]SSL Provider: [error:1416F086:SSL routines:tls_process_server_certificate:certificate verify failed:self signed certificate]
        )

    [1] => Array
        (
            [0] => 08001
            [SQLSTATE] => 08001
            [1] => -1
            [code] => -1
            [2] => [Microsoft][ODBC Driver 18 for SQL Server]Client unable to establish connection. For solutions related to encryption errors, see https://go.microsoft.com/fwlink/?linkid=2226722
            [message] => [Microsoft][ODBC Driver 18 for SQL Server]Client unable to establish connection. For solutions related to encryption errors, see https://go.microsoft.com/fwlink/?linkid=2226722
        )

)

To connect I have something like this:

$params = [
    "UID" => $username,
    "PWD" => $password,
    "Database" => $database,
    "TrustServerCertificate" => "yes"
];
if(sqlsrv_connect($host, $params)) {
    echo "connected..";
} else {
    echo "Connection could not be established.<br />";
    echo "<pre>";
    die( print_r( sqlsrv_errors(), true));
    echo "</pre>";
}

So I already use "TrustServerCertificate" => "yes" as mentioned here for fixing that error > ODBC Driver 18 for SQL Server]SSL Provider: [error:1416F086]


Solution

  • In sqlsrv_connect when passing params TrustServerCertificate needs true/false value - not 'yes/no' (they use yes/no in Microsoft docs and it might be confusing sometimes) so:

    $params = [
        "UID" => $username,
        "PWD" => $password,
        "Database" => $database,
        "TrustServerCertificate" => true
    ];
    if(sqlsrv_connect($host, $params)) {
        echo "connected..";
    } else {
        echo "Connection could not be established.<br />";
        echo "<pre>";
        die( print_r( sqlsrv_errors(), true));
        echo "</pre>";
    }
    

    and that is how it works.

    As mentioned here 3 things are important when implementing a secure (encrypted) connection to MSSQL:

    1. The options Encrypt and TrustServerCertificate are often used together.
    2. By default the SQL server installs a self-signed certificate that it will use to encrypt connections.
    3. After replacing your certificate, you then set Encrypt = true and TrustServerCertificate = false (TrustServerCertificate = true will also work, but your connection will then be vulnerable to attacks)