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($fp, 8192);
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";
}
?>
openssl_verify
(PHP 4 >= 4.0.4, PHP 5)
openssl_verify — 署名を検証する
説明
openssl_verify() は、 pub_key_id が指す公開鍵を使用し、 指定した data に関して signature が正しいことを確認します。 署名が正しいと判定されるためには、 その公開鍵が署名の際に使用した秘密鍵に対応していることを必要とします。
パラメータ
- data
-
- signature
-
- pub_key_id
-
- signature_alg
-
デフォルト値は OPENSSL_ALGO_SHA1 です。 詳細な情報は、 署名アルゴリズム の一覧を参照ください。
返り値
署名 (signature) が正しい場合に 1、正しくない場合に 0、 エラーの場合に -1 を返します。
変更履歴
| バージョン | 説明 |
|---|---|
| 5.0.0 | signature_alg パラメータが追加されました。 |
例
例1 openssl_verify() の例
<?php
// $data および $signature はデータおよび署名が含まれていると仮定
// 認証局から公開鍵を取得し、使用可能にする
$fp = fopen("/src/openssl-0.9.6/demos/sign/cert.pem", "r");
$cert = fread($fp, 8192);
fclose($fp);
$pubkeyid = openssl_get_publickey($cert);
// 署名が正しいかどうかを確認
$ok = openssl_verify($data, $signature, $pubkeyid);
if ($ok == 1) {
echo "正しいです";
} elseif ($ok == 0) {
echo "正しくありません";
} else {
echo "署名を確認する際にエラーが発生しました";
}
// メモリからキーを開放
openssl_free_key($pubkeyid);
?>
openssl_verify
Stiv
02-Mar-2006 02:34
02-Mar-2006 02:34
devel@no-spam
15-Jun-2005 01:25
15-Jun-2005 01:25
It should be noted that in order to verify a signature successfully, SHA-1 must be used to digest the data before signing.
If, for example, you are using Java to create a signature and you want to verify it in PHP, you must not use "MD5withRSA" or "SHA512withRSA" as the signature algorithm. Use "SHA1withRSA" or the like...
steve dot venable at lmco dot com
30-May-2002 07:36
30-May-2002 07:36
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.
meint dot post at bigfoot dot com
09-Jun-2001 06:56
09-Jun-2001 06:56
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 :-)
