PDO and openssl_public_decrypt failing

2019-07-25 15:52发布

问题:

I am trying to decrypt and update password into a mysql database table. while doing it is giving me a weird error.

PHP Warning: PDO::exec(): SSL operation failed with code 1. OpenSSL Error messages: error:0906D06C:PEM routines:PEM_read_bio:no start line in .../vendor/robmorgan/phinx/src/Phinx/Db/Adapter/PdoAdapter.php on line 306 PHP Warning: PDO::exec(): MySQL server has gone away in .../vendor/robmorgan/phinx/src/Phinx/Db/Adapter/PdoAdapter.php on line 306 PHP Warning: PDO::exec(): Error reading result set's header in ../vendor/robmorgan/phinx/src/Phinx/Db/Adapter/PdoAdapter.php on line 306

  • passwords are encrypted using private key.
    • openssl_private_encrypt function is used for encryption.
  • decryption is done using openssl_public_decrypt
  • encryption along with insertion into databse works fine
  • decryption along with update does not work. PDO::exec fails for some reason
  • Platform i am using is Ubuntu, PHP 5.6.24-1+deb.sury.org~xenial+1
  • Encrypt-Insert, Decrypt-Update is the order of operations.
  • Mysql connection is open before encryption and decryption is performed

code for encryption decryption:

 function processPlainText($plainText, $action) {
        $cryptText = '';
        $res = 'encrypt' == $action ? openssl_get_privatekey($this->keyContents) : openssl_get_publickey($this->keyContents);
        $action = 'encrypt' == $action ? 'openssl_private_' . $action : 'openssl_public_'.$action;

        $action($plainText, $cryptText, $res);
        openssl_free_key($res);
        return $cryptText;
    }

Any insight on this problem would be much appreciated.

Code that works:

$pdo = getMysqlPdoInstance(); //get pdo instance using ssl
$id = 101;
$plainText = 'abcd';
$password = processPlainText($plainText, 'encrypt');
$count = $pdo->exec(sprintf("UPDATE table set password =  '%s' WHERE id = %d", $password, $id));
print("Updated $count rows.\n");

Code that fails:

$pdo = getMysqlPdoInstance(); //get pdo instance using ssl
$id = 101;
$password = processPlainText($encryptedPassword, 'decrypt');
$count = $pdo->exec(sprintf("UPDATE table set password =  '%s' WHERE id = %d", $password, $id));
print("Updated $count rows.\n");

Thanks

回答1:

Using SSL for the Mysql connection made you hit a bug, resolved with a patch ("openssl_decrypt triggers bug in PDO") to PHP 7.1, with no backports yet. In the last comment at the time of writing, instructions to a workaround can be found:

.. please call openssl_error_string() after openssl_pkey_get_public in your app / script.

in your function, place while(openssl_error_string() !== false); above openssl_free_key() if you cannot move to PHP7.1.

In your comments you suspected properly, that "PDO in some way is facing [a] problem when openssl_public_decrypt is used.."