chrisvpearse/code-encrypter-laravel
Composer 安装命令:
composer require chrisvpearse/code-encrypter-laravel
包简介
A code encrypter for the Laravel framework.
README 文档
README
The goal of this open source package is security through obscurity.
It aims to offer an alternative to delivering your closed source projects in plain text. Instead, you can opt to deliver your files encrypted, alongside a binary PHP extension which will decrypt them on the fly.
This package uses symmetric encryption, which means that the key itself has to be embedded within the binary PHP extension. However, the code for the extension which holds the key and handles the decryption is open source (and is included within this package).
The key is generated by you and only known to you (as the developer). It can be unique per project and/or customer which opens up the possibility of additional functionality later down the line, such as setting expiry dates (for free trials) and/or whitelisting by IP/MAC address.
Requirements
- macOS
- PHP 8.1
- Laravel 10
- Zephir
Installation
The below assumes that you're currently in your application's root directory.
$ composer require chrisvpearse/code-encrypter-laravel
Publish the Config File
$ php artisan vendor:publish --tag=code-encrypter-config
Zephir Quickstart
You should be able to get started with Zephir by downloading the latest release PHAR from GitHub, followed by these commands:
$ cd ~ && pecl install zephir_parser
$ cd ~/Downloads && mv zephir.phar /usr/local/bin/zephir && chmod +x /usr/local/bin/zephir
A "Hello, World!" Walkthrough
Again, the below assumes that you're currently in your application's root directory.
Make an Invokable Controller
$ php artisan make:controller HelloWorld --invokable
📄 ./app/Http/Controllers/HelloWorld.php
<?php namespace App\Http\Controllers; class HelloWorld extends Controller { public function __invoke() { return 'Hello, World!'; } }
Update the Web Routes File
📄 ./routes/web.php
<?php use App\Http\Controllers\HelloWorld; use Illuminate\Support\Facades\Route; Route::get('/', HelloWorld::class);
Update the Config File
The default configuration file is shown below.
- The
*wildcard matches all files within the specified directory - The
**wildcard is recursive and matches all files within the specified directory and subdirectories
📄 ./config/code-encrypter.php
<?php return [ 'paths' => [ app_path('Http/Controllers/Foo/*'), app_path('Http/Controllers/Bar/**'), app_path('Http/Controllers/HelloWorld.php'), ], 'cipher' => config('app.cipher') ?: 'AES-256-CBC', 'minify' => false, ];
A PHP file is considered valid provided that the following conditions are met:
- The extension is: .php
- It contains an opening PHP tag:
<?php - It does not contain a closing PHP tag:
?>
First Run
You should confirm that you can see "Hello, World!" after running the following command:
$ php artisan serve
Run the Encrypt Command
$ php artisan code:encrypt
The output from the above command will be similar to the following:
Encrypted ....................................................... app/Http/Controllers/HelloWorld.php
[ INFO ] Command successfully completed.
Key ............................................. base64:8dsiWW4Ue016d1TBalTlJAE46vfO91y5/Xu9UFZzhmc=
Cipher .................................................................................. AES-256-CBC
Zephir File .......................................... tmp/code-encrypter/zephir/zephir/encrypter.zep
Zephir Temp Directory (Must Delete) .............................................. tmp/code-encrypter
❗ Please remember to make a note of your key.
On this run, one file has been successfully encrypted:
📄 ./app/Http/Controllers/HelloWorld.php
<?php \Zephir\Encrypter::decrypt("c3DHmSPBpjBUQcZ...8+SePRyCXaKbg==", "hj54ztR3KB+7cWKVJFP0QA=="); // base64:eyJpdiI6ImhqNTR6dFIzS0IrN2NXS1...UwZGVhYTY2MDRhIiwidGFnIjoiIn0=
The decrypt() static method in \Zephir\Encrypter takes the value and iv (initialization vector) from the payload returned by the encryptString() method in \Illuminate\Encryption\Encrypter.
The commented-out base64 encoded string contains the entire JSON payload returned by the encryptString() method in \Illuminate\Encryption\Encrypter and is used in the decryption process.
A "Utils" Gist
For your convenience, I have published a GitHub Gist which exposes a small number of utilities which will be used throughout the rest of this document.
Build the PHP Extension
At this point, you must build the PHP extension because Laravel will no longer be able to find \App\Http\Controllers\HelloWorld (which will result in an error).
You should switch to the Zephir Temp Directory as detailed on the output from the previous command:
$ cd tmp/code-encrypter
From there, you should initialize Zephir into the zephir directory which has already been created for you:
$ zephir init zephir
Finally, you should step into the zephir directory and build the extension from there:
$ cd zephir && zephir build
Once the extension has been built, you should be prompted to add extension=zephir.so to your php.ini file. For this, I will use the ini utility exposed by the GitHub Gist:
$ php ~/Downloads/utils.php ini
Next, we can take a look at the Zephir code itself:
📄 ./tmp/code-encrypter/zephir/zephir/encrypter.zep
namespace Zephir;
class Encrypter
{
public static function decrypt(var gLIEokrXlBB6s, var LxARS8923aokLv)
{
return eval(self::ssjgKzuSCrh9Zjhom1P(gLIEokrXlBB6s, LxARS8923aokLv));
}
...
protected static function ssjgKzuSCrh9Zjhom1P(var gLIEokrXlBB6s, var LxARS8923aokLv)
{
var ZURmZSyHXCWAwv;
let ZURmZSyHXCWAwv = ["f1","db","22","59","6e","14",..."bd","50","56","73","86","67"];
return openssl_decrypt(
gLIEokrXlBB6s,
"AES-256-CBC",
hex2bin(implode(ZURmZSyHXCWAwv)),
0,
base64_decode(LxARS8923aokLv)
);
}
...
}
The above code is not minified, which can (and should) be changed in ./config/code-encrypter.php. During the minifying process, whitespace is randomly added to ensure that the key is never in the same place twice (within the binary PHP extension).
In an effort to further randomize the binary, the \Illuminate\Support\Str::password() helper is used to name the variables and methods. Additionally, the method which holds the key is shuffled with 4–8 unused methods (each containing their own key). Each key is stored within its own array to avoid being detected by the strings command:
$ strings /path/to/zephir.so
Now, let's use the tmp utility exposed by the GitHub Gist to delete the Zephir Temp Directory:
$ php ~/Downloads/utils.php tmp "/path/to/app/root/"
Second Run
You should confirm that you are still able to see "Hello, World!" after running the following command:
$ cd ../../../ && php artisan serve
Congratulations 🎉 Your encrypted files are now being decrypted on the fly!
Run the Decrypt Command
In order to decrypt your code, you must supply the key as the first argument:
$ php artisan code:decrypt base64:8dsiWW4Ue016d1TBalTlJAE46vfO91y5/Xu9UFZzhmc=
The output from the above command will be similar to the following:
Decrypted ....................................................... app/Http/Controllers/HelloWorld.php
[ INFO ] Command successfully completed.
On this run, one file has been successfully decrypted:
📄 ./app/Http/Controllers/HelloWorld.php
<?php namespace App\Http\Controllers; class HelloWorld extends Controller { public function __invoke() { return 'Hello, World!'; } }
Run the Encrypt Command (Again)
Once the PHP extension has been built by Zephir, you can decrypt and encrypt your code as many times as you like without rebuilding the extension (provided that you use the same key). The key should be supplied via an option to the command:
$ php artisan code:encrypt --key=base64:8dsiWW4Ue016d1TBalTlJAE46vfO91y5/Xu9UFZzhmc=
Note. When encrypting code, the ./tmp/code-encrypter directory will always be generated for you.
NativePHP
At the time of writing, NativePHP ships with a static PHP binary, therefore it is not possible to install additional extensions.
However, as a PoC, we can swap out the NativePHP binary with a copy of our local PHP binary (NativePHP must already be installed). For this, I will use the bin utility exposed by the GitHub Gist:
$ php ~/Downloads/utils.php bin "/path/to/app/root/"
Third Run
You should confirm that you are still able to see "Hello, World!" after running the following command:
$ php artisan native:serve
Congratulations, again 🎊 Your encrypted files are now being decrypted on the fly within NativePHP!
Credits
- Aleksandar Jevremović, et al. (2013). Using Cryptology Models for Protecting PHP Source Code.
chrisvpearse/code-encrypter-laravel 适用场景与选型建议
chrisvpearse/code-encrypter-laravel 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 8 次下载、GitHub Stars 达 8, 最近一次更新时间为 2023 年 12 月 20 日, 在 PHP 生态内属于活跃度较高的组件。
它主要适用于以下技术方向: 「code-encrypter-laravel」 「chrisvpearse」 等业务场景。在实际项目中,围绕这些方向常见需要落地的问题包括:接口对接、性能调优、并发安全、与既有框架(Laravel / ThinkPHP / Yii / Webman 等)的兼容适配,以及生产环境的日志埋点与稳定性保障。
我们在过去多个企业项目中使用过 chrisvpearse/code-encrypter-laravel 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。
基于 chrisvpearse/code-encrypter-laravel 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。
线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。
承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。
与 chrisvpearse/code-encrypter-laravel 相关的其它包
同方向 / 同关键字的高下载量 PHP Composer 包推荐,方便对比选型:
统计信息
- 总下载量: 8
- 月度下载量: 0
- 日度下载量: 0
- 收藏数: 8
- 点击次数: 11
- 依赖项目数: 0
- 推荐数: 0
其他信息
- 授权协议: MIT
- 更新时间: 2023-12-20