laravel 5.3中自定义加密服务的方案详解

5年以前  |  阅读数:1053 次  |  编程语言:PHP 

前言

本文介绍的是laravel 5.3中自定义加密服务的方案,利用laravel的服务容器,实现自定义加密服务注册(示例是支持长字符串的RSA加密),下面来看看详细的介绍:

创建加密解密服务类

文件地址 /app/Service/Common/CryptService.php 代码如下

下面这个是个人写的支持长字符串的RSA加密类作为示例,自定义加密的话只需更改这个文件的代码就好,其它操作只是为了实现依赖注入。


    <?php
    namespace App\Service\Common;
    class CryptService
    {
     public $config,$keypath, $prikey_path, $pubkey_path, $prikey, $pubkey , $private_key_size;

     public function select($select = 'rsa_api')
     {
      $config = config('crypt');
      if (array_key_exists($select, $config)) {
       $this->config = $config[$select];
       $this->private_key_size = $this->config['openssl_config']['private_key_bits'];
      } else {
       return false;
      }
      $this->keypath = dirname(dirname(dirname(__DIR__))) . $this->config['path'];
      if(!file_exists($this->keypath)){
       mkdir($this->keypath,"0777",true);
      }
      $this->prikey_path = $this->keypath . $this->config['private_key_file_name'];
      $this->pubkey_path = $this->keypath . $this->config['public_key_file_name'];
      if (file_exists($this->prikey_path))
       $this->prikey = file_get_contents($this->prikey_path);
      if (file_exists($this->pubkey_path))
       $this->pubkey = file_get_contents($this->pubkey_path);
      return $this;
     }

     public function makeKey()
     {
      $res = openssl_pkey_new($this->config['openssl_config']);
      openssl_pkey_export($res, $this->prikey);
      file_put_contents($this->prikey_path, $this->prikey);
      $pubkey = openssl_pkey_get_details($res);
      $this->pubkey = $pubkey['key'];
      file_put_contents($this->pubkey_path, $this->pubkey);
      return $test = ['prikey' => $this->prikey, 'pubkey' => $this->pubkey];
     }

     public function encryptPrivate($data){
      $crypt = $this->encrypt_split($data);
      $crypted = '';
      foreach ($crypt as $k=>$c){
       if($k!=0) $crypted.="@";
       $crypted.=base64_encode($this->doEncryptPrivate($c));
      }
      return $crypted;
     }
     public function encryptPublic($data){
      $crypt = $this->encrypt_split($data);
      $crypted = '';
      foreach ($crypt as $k=>$c){
       if($k!=0) $crypted.="@";
       $crypted.=base64_encode($this->doEncryptPublic($c));
      }
      return $crypted;
     }

     public function decryptPublic($data){
      $decrypt = explode('@',$data);
      $decrypted = "";
      foreach ($decrypt as $k=>$d){
       $decrypted .= $this->doDecryptPublic(base64_decode($d));
      }
      return $decrypted;
     }
     public function decryptPrivate($data){
      $decrypt = explode('@',$data);
      $decrypted = "";
      foreach ($decrypt as $k=>$d){
       $decrypted .= $this->doDecryptPrivate(base64_decode($d));
      }
      return $decrypted;
     }
     private function encrypt_split($data){
      $crypt=[];$index=0;
      for($i=0; $i<strlen($data); $i+=117){
       $src = substr($data, $i, 117);
       $crypt[$index] = $src;
       $index++;
      }
      return $crypt;
     }
     private function doEncryptPrivate($data)
     {
      $rs = '';
      if (@openssl_private_encrypt($data, $rs, $this->prikey) === FALSE) {
       return NULL;
      }
      return $rs;
     }

     private function doDecryptPrivate($data)
     {
      $rs = '';
      if (@openssl_private_decrypt($data, $rs, $this->prikey) === FALSE) {
       return null;
      }
      return $rs;
     }
     private function doEncryptPublic($data){
      $rs = '';
      if (@openssl_public_encrypt($data, $rs, $this->pubkey) === FALSE) {
       return NULL;
      }
      return $rs;
     }
     private function doDecryptPublic($data)
     {
      $rs = '';
      if (@openssl_public_decrypt($data, $rs, $this->pubkey) === FALSE) {
       return null;
      }
      return $rs;
     }
    }

创建门面facades

文件地址 /app/Facades/CryptFacades.php 代码如下:


    <?php
    namespace App\Facades;
    use \Illuminate\Support\Facades\Facade;

    class CryptFacades extends Facade{
     public static function getFacadeAccessor()
     {
      return 'MyCrypt';
     }
    }

注册服务

创建文件 /app/Providers/MyCryptServiceProvider.php 代码如下:

其实也可以在AppServiceProvider中注册,就不用另外建个MyCryptServiceProvider.php文件了

而且在/config/app.php中一般也已经有了AppServiceProvider的声明


    <?php
    namespace App\Providers;

    use App\Service\Common\CryptService;
    use Illuminate\Support\ServiceProvider;

    class MyCryptServiceProvider extends ServiceProvider
    {
     /**
      * Bootstrap the application services.
      *
      * @return void
      */
     public function boot()
     {
      //
     }

     /**
      * Register the application services.
      *
      * @return void
      */
     public function register()
     {
      \App::bind('MyCrypt',CryptService::class);
     }
    }

在配置中声明

文件地址 /config/app.php 在providershe和aliases中添加


    'providers' => [
     \App\Providers\MyCryptServiceProvider::class,
    ],

    'aliases' => [
     'MyCrypt' => \App\Facades\CryptFacades::class,
    ]

编写自定义加密解密服务的配置文件

/config/crypt.php 因为我写的CryptService有用到配置文件,所以需要再添加个配置文件。在实际项目中,可以根据需要自行设置配置文件和加密服务类。


    <?php
    //基于laravel根目录,分隔符最好是用 DIRECTORY_SEPARATOR 常量代替
    return [
     'rsa_api' => [
      'path'=>DIRECTORY_SEPARATOR.'storage'.DIRECTORY_SEPARATOR.'rsakey'.DIRECTORY_SEPARATOR,
      'private_key_file_name'=>'private_key.pem',
      'public_key_file_name' =>'public_key.pem',
      'openssl_config'=>[
       "digest_alg" => "sha512",
       "private_key_bits" => 1024,
       "private_key_type" => OPENSSL_KEYTYPE_RSA,
      ]
     ],
     'rsa_data'=>[
      'path'=>DIRECTORY_SEPARATOR.'storage'.DIRECTORY_SEPARATOR.'rsakey'.DIRECTORY_SEPARATOR,
      'private_key_file_name'=>'private.pem',
      'public_key_file_name' =>'public.pem',
      'openssl_config'=>[
       "digest_alg" => "sha512",
       "private_key_bits" => 1024,
       "private_key_type" => OPENSSL_KEYTYPE_RSA,
      ]
     ]
    ];

在Controller中使用的示例

1、artisan创建Controller文件


    php artisan make:controller IndexController

2、编辑IndexController


    <?php
    namespace App\Http\Controllers;

    use Illuminate\Http\Request;
    use MyCrypt;
    class IndexController extends Controller{

     public function test(){
      $crypt = MyCrypt::select('rsa_api');
      $crypt->makeKey();
      $short = "abcd";
      $long = "
       aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
       aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
       aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
       aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
       aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
       aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
       aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
       aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
       aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
       aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
       aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
       aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";

      $req['short'] = $short;
      $req['short_private_encrypt'] = $crypt->encryptPrivate($short);
      $req['short_public_decrypt'] = $crypt->decryptPublic($req['short_private_encrypt']);

      $req['long'] = $long;
      $req['long_private_encrypt'] = $crypt->encryptPrivate($long);
      $req['long_public_decrypt'] = $crypt->decryptPublic($req['long_private_encrypt']);
      dump($req);
      //dd($req);
     }
    }

3、在/routes/web.php添加路由


    Route::get('/test', 'IndexController@test');

4、浏览器访问验证结果

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流,谢谢大家对脚本之家的支持。

 相关文章:
PHP分页显示制作详细讲解
SSH 登录失败:Host key verification failed
获取IMSI
将二进制数据转为16进制以便显示
获取IMEI
文件下载
贪吃蛇
双位运算符
PHP自定义函数获取搜索引擎来源关键字的方法
Java生成UUID
发送邮件
年的日历图
提取后缀名
在Zeus Web Server中安装PHP语言支持
让你成为最历害的git提交人
Yii2汉字转拼音类的实例代码
再谈PHP中单双引号的区别详解
指定应用ID以获取对应的应用名称
Python 2与Python 3版本和编码的对比
php封装的page分页类完整实例