php使用rsa公钥私钥加密解密
未知
2020-10-27 11:42:12
0
首先要使用openssl提供的函数,PHP需要此扩展:

编译时加上此配置即可:–with-openssl=/path/to/ssl

首先看看如何对数据进行签名:

        $data-='12345';
        //私钥及密码
        $privatekeyFile='/private.key';
        $passphrase='';
        //摘要及签名的算法
        $digestAlgo='sha256';
        $algo=OPENSSL_ALGO_SHA256;
        //加载私钥
        $privatekey=openssl_pkey_get_private(file_get_contents($privateFile),$passphrase);
        //生成摘要
        $digest=openssl_digest($data,$digestAlgo);
        //签名
        $signature='';
        openssl_sign($digest,$signature,$privatekey,$algo);
        $signature=base64_encode($signature);
        var_dump($signature);


这里我们学习到了三个openssl的方法:


openssl_pkey_get_private ( mixed $key [, string $passphrase = “” ] ) 此方法用于加载私钥。
$key接受的参数可以是私钥文件(协议+文件路径)或者私钥的内容。如上面代码里的方式是后者,如果换成第一种方式则是:

        privatekey=opensslpkeygetprivate(“file://privatekey=opensslpkeygetprivate(“file:// privatekey = openssl_pkey_get_private(“file://privatekey=opensslp​keyg​etp​rivate(“file://privatekeyFile”, $passphrase);

$passphrase参数为私钥的密码,如果私钥没有密码的话,可以不传或者传空。 此外,这个方法还有个别名:openssl_get_privatekey。


openssl_digest ( string $data , string $method [, bool $raw_output = false ] ) 此方法用于对数据进行摘要计算。
$data是需要生成摘要的数据。
$method是生成摘要的算法。摘要支持哪些算法,请参照附录1.
$raw_output表示是否返回原始数据,如果为false(默认)的话则返回binhex编码后的数据。

事实上摘要的生成可以不使用openssl的这个方法,因为其实生成摘要就是对数据进行hash,我们可以用以下代码取代摘要生成部分:

 if (function_exists(‘hash’)) { digest=hash(digest=hash(      digest = hash(digest=hash(digestAlgo, $data, TRUE); } elseif (function_exists(‘mhash’)) { digest=mhash(constant(“MHASH”.strtoupper(digest=mhash(constant(“MHASH”.strtoupper(      digest =mhash(constant(“MHASH_” . strtoupper(digest=mhash(constant(“MHASH”​.strtoupper(digestAlgo)), $data); } digest=bin2hex(digest=bin2hex(      digest = bin2hex(digest=bin2hex(digest);


使用hash方法有个好处就是支持的算法要比openssl_digest多很多。具体支持的算法可以调用hash_algos()方法查看。


openssl_sign ( $data , string &̲signature , mixed $priv_key_id [, int $signature_alg = OPENSSL_ALGO_SHA1 ] ) 此方法用于对数据进行签名。
$data为需要进行签名的数据,一般为摘要。
$signature为调用成功后生成的签名。
$priv_key_id是openssl_pkey_get_private方法返回的资源标识符。 $signature_alg是签名使用的算法,默认为OPENSSL_ALGO_SHA1。支持的算法请参照附录1。

为什么要先生成摘要再签名?因为用私钥签名是比较耗时耗性能的,特别是在数据比较大的情况下。而摘要算法可以很快的生成一串很短的字符串。用这串东西去签名就快很多了。

OK。下面我们看看如何验签:



        $data-='12345';
        //公钥
        $publickeyFile='/public.key';
        //摘要及签名的算法
        $digestAlgo='sha256';
        $algo=OPENSSL_ALGO_SHA256;
        //加载公钥
        $publickey=openssl_pkey_get_public(file_get_contents($publickeyFile));
        //生成摘要
        $digest=openssl_digest($data,$digestAlgo);
        //验签
        $verify=openssl_verify($digest,base64_decode($signature),$publickey,$algo);

        var_dump($verify);//int(1)表示验签成功



生成摘要的算法以及验签的算法必须跟签名时保持一致。


这里,我们又学习到两个新的方法:

openssl_pkey_get_public ( mixed $certificate ) 这个方法用于加载公钥。 $certificate为公钥的内容。 同样,这个方法也有个别名:此外,这个方法还有个别名:openssl_get_publickey。

openssl_verify ( string $data , string $signature , mixed $pub_key_id [, int $signature_alg = OPENSSL_ALGO_SHA1 ] ) 此方法用于验签。 $data为用于生成签名的数据。 $signature为上一步生成的签名。 $pub_key_id为加载的公钥。 $signature_alg为验签的算法。对应签名的算法。

简单说完签名与验签,下面我们说说加密及解密。

        $data-='12345';

        //公钥

        $publickeyFile='/public.key';

        //加载公钥

        $publickey=openssl_pkey_get_public(file_get_contents($publickeyFile));

        //使用公钥进行加密

        $encryptedData='';

        openssl_public_encrypt($data,$encryptedData,$publickey);

        var_dump(base64_encode($encryptedData));

        


先看看加密: 再看看解密:

        $data-='12345';

        //base64_encode加过密的数据

        $encryptedData='xxxxxxxx';

        //私钥及密码

        $privatekeyFile='/private.key';

        $passphrase='';

        //加载私钥

        $privatekey=openssl_pkey_get_public(file_get_contents($privatekeyFile),$passphrase);

        //使用公钥进行加密

        $sensitiveData='';

        openssl_private_decrypt(base64_decode($encryptedData),$sensitiveData,$privatekey);

        var_dump($sensitiveData);//应该跟$data一致


很简单。这里我们又学到两个新的方法:


openssl_public_encrypt ( string KaTeX parse error: Expected 'EOF', got '&' at position 15: data , string &̲crypted , mixed $key [, int $padding = OPENSSL_PKCS1_PADDING ] )此方法用于使用公钥进行加密。 $data为需要加密的数据。 $crypted为加密后的数据。 $key为公钥。 $padding为填充方式,默认为OPENSSL_PKCS1_PADDING,还可以是如下几个值:OPENSSL_SSLV23_PADDING, OPENSSL_PKCS1_OAEP_PADDING, OPENSSL_NO_PADDING。

openssl_private_decrypt ( string KaTeX parse error: Expected 'EOF', got '&' at position 15: data , string &̲decrypted , mixed $key [, int $padding = OPENSSL_PKCS1_PADDING ] ) 此方法用于使用私钥进行解密。 $data为需要解密的数据。 $decrypted为解密后的数据。 $key为私钥。 $padding为填充方式。

目前还没弄清楚各种填充方式的使用场景。

公钥加密的数据只能用私钥进行解密,而用私钥加密的数据只能用公钥进行解密。上面的代码描述的是前者。而后者对应的方法是:openssl_private_encrypt和openssl_public_decrypt。这两个方法跟上面类似,这里不作解释。

事实上,在HTTPS里,数据的加密和解密并不是直接使用公钥和私钥进行的,而是使用另外一个密钥进行对称加密跟解密。公钥跟私钥是用来加密跟解密这个密钥的。为什么要这样做了,理由跟上面讲到的签名一样,用公钥加密大数据是比较耗时耗性能的。

附录1 签名算法:

算法    备注
OPENSSL_ALGO_DSS1    此常量在PHP 5.0.0中添加
OPENSSL_ALGO_SHA1    此常量在PHP 5.0.0中添加。为openssl_sign和openssl_verify方法的默认值。
OPENSSL_ALGO_SHA224    此常量在PHP 5.4.8中添加
OPENSSL_ALGO_SHA256    此常量在PHP 5.4.8中添加
OPENSSL_ALGO_SHA384    此常量在PHP 5.4.8中添加
OPENSSL_ALGO_SHA512    此常量在PHP 5.4.8中添加
OPENSSL_ALGO_RMD160    此常量在PHP 5.4.8中添加
OPENSSL_ALGO_MD5    此常量在PHP 5.0.0中添加
OPENSSL_ALGO_MD4    此常量在PHP 5.0.0中添加
OPENSSL_ALGO_MD2    
此常量在PHP 5.0.0中添加。从PHP 5.2.13和PHP 5.3.2开始,这个常量只有在PHP编译时加入MD2的支持才有效。



按照key的ascii顺序排序,并以&作为连接符拼接成待签名串(即key1=value1&key2=value2…)。

/**
       * 拼接需要签名的内容
       * Author: Liyajun.
       *
       * @param array $data 需签名的字段内容
       *
       * @return string
       */    
     public  function getSignString($array)
    {
        foreach ($array as $k => $v) {
             $Parameters[$k] = $v;
        }
         //按字典序排序参数
        ksort($Parameters);
        $sign = '';
        foreach ($Parameters as $k => $v) {
             $sign .= $k . "=" . $v . "&";
        }
        $sign = rtrim($sign, '&');
        return $sign;
    }


上一篇:laravel 显示419错误

下一篇:零用

相关内容

如何使用MySQL变量进行...
本文详细介绍了MySQL中用户定义变量、系统变量和局部变量的使用方...
2024-11-20 18:46:45
拼多多购物优惠券,优惠力度...
拼多多购物优惠券种类多,优惠力度大,可省下不少钱。可通过平台活动、...
2024-11-20 12:00:43
PHP与SQLSRV数据库...
摘要:本文介绍了PHP与SQLSRV数据库迁移的步骤和注意事项,包...
2024-11-20 11:46:42
PHP与SQLSRV连接数...
PHP与SQLSRV连接SQL Server数据库教程,介绍安装配...
2024-11-20 11:23:44
PHP与SQLSRV连接M...
本文介绍了使用PHP和SQLSRV扩展连接MySQL数据库的实例,...
2024-11-20 11:00:46
PHP中SQLSRV处理大...
摘要:在PHP中使用SQLSRV处理大数据量时,可通过数据库端索引...
2024-11-20 10:46:41

热门资讯

tp5 jquery判断手机端... application--common.php中添加如下代码 //函数作用是判断用户打开的是手机端还...
Laravel 5.5 .No... 创建了新的laravel项目后, 运行提示:No application encryption ke...
php 打印date函数出现错... 问题描述: 我使用的是phpstudy,在练习时间函数的时候,打印出现在的时间,date(Y-m-d...
生成随机字符唯一标识符guid... /** * @param $length * @return string * 生成随机字符串 */...
layui缩略图 div class=layui-form-item label class=layui-form-l...
php函数substr_rep... php函数substr_replace从某个位置替换或删除或插入字符串
Laravel 引入自定义类库... 强烈建议引入的类 都是含有命名空间的,这样使用起来就不会出现重名的情况。!!当然,没有命名空间也可以...
object json转化为数... //调用api 程序,通知商户订单异常 20200314 public function callt...
Laravel 查看SQL操作... 方法一:临时打印操作记录 DB::connection()-enableQueryLog(); # ...
php银行开放平台接口:pfx... 问题描述: 对接易通银行,他们的服务开放平台是java开发,而我的是php,现在需要php版本的SD...