文字

openssl_verify

(PHP 4 >= 4.0.4, PHP 5)

openssl_verifyVerify signature

说明

int openssl_verify ( string $data , string $signature , mixed $pub_key_id [, mixed $signature_alg = OPENSSL_ALGO_SHA1 ] )

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.

参数

data

The string of data used to generate the signature previously

signature

A raw binary string, generated by openssl_sign() or similar means

pub_key_id

resource - a key, returned by openssl_get_publickey()

string - a PEM formatted key, example, "-----BEGIN PUBLIC KEY----- MIIBCgK..."

signature_alg

int - one of these Signature Algorithms.

string - a valid string returned by openssl_get_md_methods() example, "sha1WithRSAEncryption" or "sha512".

返回值

Returns 1 if the signature is correct, 0 if it is incorrect, and -1 on error.

更新日志

版本 说明
5.2.0 The signature_alg parameter was added.

范例

Example #1 openssl_verify() example

<?php
// $data and $signature are assumed to contain the data and the signature

// fetch public key from certificate and ready it
$pubkeyid  openssl_pkey_get_public ( "file://src/openssl-0.9.6/demos/sign/cert.pem" );

// state whether signature is okay or not
$ok  openssl_verify ( $data $signature $pubkeyid );
if (
$ok  ==  1 ) {
    echo 
"good" ;
} elseif (
$ok  ==  0 ) {
    echo 
"bad" ;
} else {
    echo 
"ugly, error checking signature" ;
}
// free the key from memory
openssl_free_key ( $pubkeyid );
?>

Example #2 openssl_verify() example

<?php
//data you want to sign
$data  'my data' ;

//create new private and public key
$private_key_res  openssl_pkey_new (array(
    
"private_key_bits"  =>  2048 ,
    
"private_key_type"  =>  OPENSSL_KEYTYPE_RSA ,
));
$details  openssl_pkey_get_details ( $private_key_res );
$public_key_res  openssl_pkey_get_public ( $details [ 'key' ]);

//create signature
openssl_sign ( $data $signature $private_key_res "sha1WithRSAEncryption" );

//verify signature
$ok  openssl_verify ( $data $signature $public_key_res OPENSSL_ALGO_SHA1 );
if (
$ok  ==  1 ) {
    echo 
"valid" ;
} elseif (
$ok  ==  0 ) {
    echo 
"invalid" ;
} else {
    echo 
"error: " . openssl_error_string ();
}
?>

参见

  • openssl_sign() - Generate signature

用户评论:

[#1] attila dot m dot magyar at gmail dot com [2014-08-26 21:37:52]

mikey at badpenguins dot com -- validating an X509 certificate chain in php seems to be possible with openssl_x509_checkpurpose()

[#2] jeremie dot gomez at gmail dot com [2011-08-31 11:08:53]

You can actually use the public key as third parameter and not the certificate.

If you can't make it work, make sure that :

1) Your public key is well formatted. It seems that it must have the ----BEGIN PUBLIC KEY---- and ----END PUBLIC KEY----

2) Your signature is in binary format. You can use the php base64_decode for this.

[#3] mikey at badpenguins dot com [2010-06-06 21:04:45]

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.

I had to write my own code to determine if one cert signed another, it is located here: http://badpenguins.com/source/misc/isCertSigner.php?viewSource

In a nutshell here is what I learned...

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.

[#4] Stiv [2006-03-02 06:34:57]

I've finally found a way to verify signature. Sample in the documentation doesn't work. Code bellow DOES work :)

<?php
// $data is assumed to contain the data to be signed

// fetch certificate from file and ready it
$fp fopen("path/file.pem""r");
$cert fread($fp8192);
fclose($fp);

// state whether signature is okay or not
// use the certificate, not the public key
$ok openssl_verify($data$signature$cert);
if (
$ok == 1) {
    echo 
"good";
} elseif (
$ok == 0) {
    echo 
"bad";
} else {
    echo 
"ugly, error checking signature";
}
?>

[#5] steve dot venable at lmco dot com [2002-05-30 12:36:09]

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.

[#6] meint dot post at bigfoot dot com [2001-06-09 11:56:41]

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:

N = Len(Blob.Hex)

' reverse bytes in the signature using Hex format 
For i = 1 To N - 1 Step 2 
s = Mid(Blob, i, 2) & s 
Next 

s contains the digital signature in reverse order. Blob is an arbitrary binary container.

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 :-)

上一篇: 下一篇: