openssl_verify

Descrierea

openssl_verify() verifies that the
signature is correct for the specified
data using the public key associated with
pub_key_id. This must be the public key
corresponding to the private key used for signing.

A se vedea și

User Contributed Notes 6 notes

I spent days scouring the php openssl documentation trying to figure out how to do what sounds like a simple task - given two PEM encoded certificates, is one the signer of the other? Nowhere in the openssl_verify() documentation or comments is it explained where to obtain the signature of an existing certificate. The openssl_x509_parse() function looked promising, but it is an unstable API that may change.

The signature data in a signed X.509 certificate contains DER formatted data about the signature that is encrypted with the signers public key. The data contains a hash of the original subject certificate and information about what encryption algorithm was used to create the signature.

So you need to get this signature data and a copy of the original certificate with the issuer and signature sequences removed. Hash a copy of the original certificate (sans issuer/signature sequences) with the same algorithm the issuer used and if the hashes match, you have the issuer cert that signed the certificate.

Anbybody trying to get a Win32 CryptoAPI based digital signature component to work with the openssl_verify() function should be aware that the CryptoAPI PKCS1 (RSA) method uses bytes in reverse order while the openssl_verify() method expects a correctly formatted PKCS1 digital signature (as should be). I learned this the hard way and it took me some time to dig this out. A simple solution in VBScript to reverse the byte order:

Send the signature off in Hex format and use a hex2bin method in PHP to convert to the correct format for openssl_verify(), i.e.

function hex2bin($data) {

$len = strlen($data);
return pack("H" . $len, $data);

}

That's it, hope it helps out. BTW I used ASPEncrypt to toy around with on Win32 platform. Works only with Internet Explorer but you could also use a Java applet and have none of the abovementioned problems :-)

A note about the openssl_verify() (and some of the other functions). The public key comes from a certificate in any of the support formats (as the example shows, use openssl_get_publickey() to get the resource id). But after some trial and error I found the signature string MUST BE BINARY. While no error occurs, passing a base64-formatted signature string (PEM format?), you simply get a mismatch. When I did the base64 decode myself, the verify returned a match (return value 1). You can simply drop the begin/end lines and take the output of the 'base64_decode()' function.