nmure/encryptor-bundle
A Symfony bundle that provides encryption and decryption services for securing sensitive data in your applications. Integrates with Symfony's service container to make encrypting values, files, or configuration straightforward within your project.
First, confront the mismatch: this is a Symfony Bundle, not a Laravel package. There is no service provider, no auto-discovery, and no facade. If you install nmure/encryptor-bundle in a Laravel app, you get a package whose DependencyInjection\EncryptorExtension and Bundle base class expect a Symfony kernel — Laravel will never boot it. The only useful thing here for a Laravel developer is the underlying library it wraps: nmure/encryptor, a thin OpenSSL wrapper with encrypt($string) / decrypt($cipher) methods.
Minimal path if you actually need it:
composer require nmure/encryptor — not the bundle.vendor/nmure/encryptor/src/Nmure/Encryptor/Encryptor.php first — it's ~100 lines. That is the whole feature set.--ignore-platform-reqs (don't, in prod).stripe_token or api_secret on a users table) before persisting, then decrypting on read.Before writing a single line of integration code, ask the real question: why not Laravel's built-in Crypt::encryptString()? Laravel already gives you AES-256-CBC + HMAC-SHA256 with key management wired to APP_KEY. The only defensible reason to reach for this package is cross-runtime interoperability: a legacy Symfony 3/4 app encrypts data, and a Laravel app must decrypt it (or vice versa). If that's not your situation, you're adding a 0-dependent, 6-year-abandoned dependency to solve a problem Laravel already solved better.
Skip the bundle entirely and bind the underlying Encryptor in a custom service provider:
// app/Providers/EncryptorServiceProvider.php
use Nmure\Encryptor\Encryptor;
public function register(): void
{
$this->app->singleton(Encryptor::class, function ($app) {
return new Encryptor(
config('encryptor.secret', $app['config']->get('app.key'))
);
});
}
Add config/encryptor.php returning ['secret' => env('ENCRYPTOR_SECRET')]. Prefer a separate secret from APP_KEY so rotating one doesn't invalidate the other's ciphertext.
Wrap it in a custom cast so encrypted columns stay encrypted across the whole app:
// app/Casts/NmureEncrypted.php
use Illuminate\Contracts\Database\Eloquent\CastsAttributes;
use Nmure\Encryptor\Encryptor;
class NmureEncrypted implements CastsAttributes
{
public function get($model, $key, $value, $attributes)
{
return $value === null ? null : app(Encryptor::class)->decrypt($value);
}
public function set($model, $key, $value, $attributes)
{
return $value === null ? null : app(Encryptor::class)->encrypt($value);
}
}
Usage:
protected $casts = ['api_secret' => NmureEncrypted::class];
Never put this cast on a column you also want to query/WHERE/ORDER BY — ciphertext is non-deterministic, so search breaks immediately. Encrypted columns are write-then-read-only.
If you have a Symfony service producing ciphertext consumed by Laravel:
nmure/encryptor version on both sides (pin in composer, don't float).For things like encrypting a webhook signing secret in a settings table, the cast pattern is overkill — just call app(Encryptor::class)->encrypt($secret) at the boundary (a SettingsRepository::putSecret() method) and decrypt() in a single getter. Keep encryption calls at the persistence edge, not scattered through controllers.
It's abandoned — treat it as vendored code, not a dependency. No release since 2017, 0 dependents, 2 stars. That means: no security patches, PHP 8+ likely unsupported, and you are your own maintainer. Fork it into your org namespace if you need it long-term. Weigh this heavily against Crypt.
Do not assume it's wire-compatible with Laravel's Crypt. Both use OpenSSL AES, but they differ in payload structure (Laravel's serialized JSON envelope + base64 + MAC vs. this library's raw openssl_encrypt output/base64). You cannot Crypt::decrypt() a string from this library or vice versa. Any migration between them is a manual re-encryption job — which itself requires decrypting every row with the old tool first. Plan that migration before you have millions of rows.
Key management is entirely on you. Unlike Laravel's APP_KEY handling, there's no key rotation, no key versioning, no cipher config. Rotating the secret means decrypting every row with the old key and re-encrypting with the new one, in a maintenance window, with a backfill you have to write. Bake a key_version column into the table now if you anticipate rotation.
PHP version + OpenSSL mode traps. If you force-install on PHP 8.x, watch for:
openssl_* returning false silently (older code often casts to string, producing "" instead of throwing). Always check if ($plain === false).create_function, or mcrypt remnants that fatal on 8.x. Run one decrypt round-trip in staging before trusting prod.The bundle's Symfony wiring is dead weight in Laravel — do not waste time trying to shoehorn NmureEncryptorBundle through a fake kernel or PackageManifest. Install the library, bind the class yourself, and move on.
Debugging decrypt failures: they almost always mean one of four things — (1) ciphertext was truncated by a VARCHAR(255) column (use TEXT/LONGTEXT), (2) the secret differs between environments (check the resolved env value, not the config file), (3) the value was double-encoded (base64-of-base64 from a bad copy/paste), or (4) a previous failed write stored "" (empty string) which decrypts to false/garbage. Add a null/empty guard before decrypting.
Extension points are minimal by design. The Encryptor class is basically a final utility — there's no cipher-strategy interface to swap. If you need AES-256-GCM (authenticated, no separate MAC) rather than CBC, you're better off writing a 30-line Crypt-based wrapper than fighting this library.
Strong recommendation: unless a cross-runtime Symfony contract forces your hand, use Crypt::encryptString() / decryptString() for new code and reserve this package only for reading legacy data — behind a repository method you can later delete wholesale during a re-encryption migration.
How can I help you explore Laravel packages today?