php使用openssl进行数字签名验证

时间:2022-05-05 12:29:37
 <?php
 /**
  * Created by PhpStorm.
  * User: hanks
  * Date: 6/2/2017
  * Time: 6:03 PM
  */
 /*
 【数字签名】
 使用完全加密的数据进行传输的好处是更加安全,但是计算更加复杂,需要传输的数据也更多,
 更常用的方式只是对要传输的数据做一个数字签名,在接收端对接收到的数据进行一个签名运算,
 只要客户端计算的签名和接受的的签名一样就可以认为收到的数据没有被篡改过。

 计算签名使用openssl提供的openssl_sign(),签名验证使用openssl_verify()
 这两个函数的函数签名为:

 bool openssl_sign ( string $data , string &$signature , mixed $priv_key_id [, mixed $signature_alg = OPENSSL_ALGO_SHA1 ] )
 int openssl_verify ( string $data , string $signature , mixed $pub_key_id [, mixed $signature_alg = OPENSSL_ALGO_SHA1 ] )
 通过参数比较容易理解函数的使用,sign函数第一个函数是一个字符串,所以对数组,
 对象等签名需要使用json_encode或者base64_encode等函数编码一下;
 第二个参数是&$signature就是函数会把对数据$data的签名保存在$signature变量。

 注意返回值,第一个函数是bool值,第二个是int,1表示签名验证通过, 0表示签名不正确,-1表示发生错误。*/

 $publicKey = file_get_contents('./php-public.key');
 $privateKey = file_get_contents('./php-private.key');

 $data = [
     'orderId' => 100002,
     'pay_time' => '2015-09-02 10:10:10',
     'extra'=>'额外的数据'
 ];
 $signature = '';
 openssl_sign(json_encode($data), $signature, $privateKey);
 echo 'sign is: ' . base64_encode($signature);

 //这里做实验,手动的篡改下orderId的键值
 //$data = [
 //    'orderId' => 100003,
 //    'pay_time' => '2015-09-02 10:10:10',
 //    'extra'=>'额外的数据'
 //];

 $verify = openssl_verify(json_encode($data), $signature, $publicKey);

 echo "\nverify result: $verify";//返回的将是0,即签名不正确,返回1,表示签名验证通过