laravel5.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中使用的示例

  • artisan创建Controller文件
php artisan make:controller IndexController
  • 编辑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);
    }
}
  • 在/routes/web.php添加路由
Route::get('/test',  'IndexController@test');
  • 浏览器访问验证结果
添加新评论