PHP wrapper for the jilapi binary fast secure encryption for strings and files.
Made with ❤️ by md-mojahed.github.io
- PHP >= 7.4
- The
jilapibinary installed and executable
composer require mojahed/jilapiuse Mojahed\Jilapi;
// absolute path, or omit to assume `jilapi` is on your PATH
$j = Jilapi::setPath('/usr/local/bin/jilapi');$b64 = $j->encryptText('hello world', 'mypassword');
$pt = $j->decryptText($b64, 'mypassword'); // raw bytes$recipient = $j->keygen(); // ['priv' => ..., 'pub' => ...]
$sender = $j->keygen();
// encrypt TO recipient, signed BY sender
$b64 = $j->encryptTextAsym('secret', $recipient['pub'], $sender['priv']);
// decrypt WITH recipient's key, verifying sender's signature
$pt = $j->decryptTextAsym($b64, $recipient['priv'], $sender['pub']);
// omit the 3rd arg to decrypt without verifying (jilapi will warn)
$pt = $j->decryptTextAsym($b64, $recipient['priv']);Asymmetric mode uses the same key-agreement primitives as TLS 1.3 (X25519 + HKDF). Signing is optional — without it, you get confidentiality only, not sender authenticity.
// symmetric
$j->encryptFile('./secret.zip', 'mypassword'); // -> secret.zip.jilapi
$j->decryptFile('./secret.zip.jilapi', 'mypassword'); // -> secret.zip
// custom output + overwrite
$j->encryptFile('./data.db', 'k', './data.enc', true);
$j->decryptFile('./data.enc', 'k', './data.db', true);
// asymmetric (+ optional signing)
$j->encryptFileAsym('./secret.zip', './recipient.pub', null, './sender.priv');
$j->decryptFileAsym('./secret.zip.jilapi', './recipient.priv', null, './sender.pub');$j->inspect('./secret.zip.jilapi'); // header metadata (string)
$j->keygen('/path/mykeys'); // -> ['priv' => ..., 'pub' => ...]
$j->version(); // "jilapi version v1.0.0"
$j->isAvailable(); // bool — handy for boot checksAll methods throw RuntimeException on failure (non-zero exit, wrong key, bad signature, etc.):
try {
$j->decryptText($b64, 'wrong-key');
} catch (\RuntimeException $e) {
echo $e->getMessage(); // jilapi error (exit 1): decryption failed: wrong key or corrupted data
}The package has no hard Laravel dependency, so it works anywhere. To use it as a singleton/facade, drop these into your app:
// app/Providers/JilapiServiceProvider.php
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
use Mojahed\Jilapi;
class JilapiServiceProvider extends ServiceProvider
{
public function register(): void
{
$this->app->singleton('jilapi', function ($app) {
return Jilapi::setPath(config('services.jilapi_binary', 'jilapi'));
});
}
}// app/Facades/Jilapi.php (optional)
namespace App\Facades;
use Illuminate\Support\Facades\Facade;
class Jilapi extends Facade
{
protected static function getFacadeAccessor(): string
{
return 'jilapi';
}
}Register the provider in config/app.php, then:
$ct = app('jilapi')->encryptText('hello', 'k');
// or with the facade
\App\Facades\Jilapi::encryptText('hello', 'k');Or bind it in a service container — no provider required:
app()->singleton('jilapi', fn () => \Mojahed\Jilapi::setPath('/usr/local/bin/jilapi'));jilapi takes the symmetric --key as a command-line argument. On multi-user / shared-host systems, other users can see process arguments via tools like ps. If that applies to you:
- prefer the asymmetric mode (no password on the command line), and/or
- run on a single-tenant host / container.
The wrapper itself escapes every argument (escapeshellarg) — it is safe from shell injection.
MIT