Search code examples
phpsoapphp-openssl

Signing data gives mismatch using openssl_sign and openssl_verify


The last few days I'm trying to produce a signature on XML data by using openssl_sign and later verify this by using openssl_verify. Unfortunately openssl_verify keeps returning false. Since I was not sure if my private and public key extracted from my certificate were OK, I also tried a basic example.

openssl_sign indeed returns a binary signature. So far so good (also did this with my private key extracted from PEM cert). Also in the example openssl_verify returns false. I Assume that the private and public keys are correct in the example. Any help in how to sign and verify?

<?php
$Data = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";

// $key_private_id = openssl_get_privatekey(file_get_contents($ClientCertFile), $passphrase);
// $key_public_id = openssl_get_publickey(file_get_contents($ClientCertFile));

$key_private_id = <<<EOD
-----BEGIN RSA PRIVATE KEY-----
MIIBOgIBAAJBANDiE2+Xi/WnO+s120NiiJhNyIButVu6zxqlVzz0wy2j4kQVUC4Z
RZD80IY+4wIiX2YxKBZKGnd2TtPkcJ/ljkUCAwEAAQJAL151ZeMKHEU2c1qdRKS9
sTxCcc2pVwoAGVzRccNX16tfmCf8FjxuM3WmLdsPxYoHrwb1LFNxiNk1MXrxjH3R
6QIhAPB7edmcjH4bhMaJBztcbNE1VRCEi/bisAwiPPMq9/2nAiEA3lyc5+f6DEIJ
h1y6BWkdVULDSM+jpi1XiV/DevxuijMCIQCAEPGqHsF+4v7Jj+3HAgh9PU6otj2n
Y79nJtCYmvhoHwIgNDePaS4inApN7omp7WdXyhPZhBmulnGDYvEoGJN66d0CIHra
I2SvDkQ5CmrzkW5qPaE2oO7BSqAhRZxiYpZFb5CI
-----END RSA PRIVATE KEY-----
EOD;    


$key_public_id = <<<EOD
-----BEGIN PUBLIC KEY-----
MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBANDiE2+Xi/WnO+s120NiiJhNyIButVu6
zxqlVzz0wy2j4kQVUC4ZRZD80IY+4wIiX2YxKBZKGnd2TtPkcJ/ljkUCAwEAAQ==
-----END PUBLIC KEY-----
EOD;

if(!openssl_sign($Data, $Signature, $key_private_id, OPENSSL_ALGO_SHA1 )) { 
    echo "Failed to sign data: $Data ";
}

if(!openssl_verify($Data, $Signature, $key_public_id, OPENSSL_ALGO_SHA1)) {
    echo "Verify failed on signed data: $Data ";
}

Solution

  • This a common mistake to make. The PHP documentation for the heredoc format says:

    Warning It is very important to note that the line with the closing identifier must contain no other characters, except a semicolon (;). That means especially that the identifier may not be indented, and there may not be any spaces or tabs before or after the semicolon.

    Ensure no trailing spaces after EOD; and things will start working. If you had enabled proper PHP error logging, you would have gotten "undefined variable" notices from the assignment statement.