erikwang2013/encryption
erikwang2013/encryption is a Laravel/PHP package for encrypting and decrypting application data. It provides straightforward helpers to secure sensitive values and integrate encryption into your Laravel projects.
Install the package as usual; nothing in v1.4.0 changes the default runtime behavior, so an existing install upgrades without code edits.
Where to look first:
EncryptionManagerFactory::fromMasterKey() — the single entry point most applications need. The shortest working path is unchanged:$manager = EncryptionManagerFactory::fromMasterKey($master);
$ct = $manager->encrypt($plaintext); // v1 derivation, byte-for-byte identical to 1.3.x
First use case to get running: encrypt/decrypt one field with AES-256-GCM through the factory, confirm round-trip, then decide your derivation scheme deliberately (see below) rather than by default.
If you are starting a greenfield project with no existing ciphertext, pass 'v2' from day one — there is no migration cost and you never inherit the reversed-HMAC semantics:
$manager = EncryptionManagerFactory::fromMasterKey($master, 'aes-256-gcm', 'v2');
Choose the scheme per data store, not per call site. The factory and the individual encryptors take the scheme independently, so the practical risk is drift: a value written by a 'v2' factory but read through a 'v1' encryptor (or vice versa) fails MAC. Pick one scheme per store/tenant and express it once — a config value, an enum, or a small wrapper — then feed both the factory and any hand-constructed encryptors from that one source.
// Three MAC-using encryptors accept the same opt-in:
new Sm4CbcEncryptor($key16, macDerivation: 'v2');
Record the scheme alongside the ciphertext. Both schemes produce ciphertext with the same on-wire prefix, so the scheme is not recoverable from the blob. Store a small version tag in your own envelope (column, JSON field, Redis key suffix) and select the decryptor from that tag. This is what makes dual-read migration possible and keeps you out of "try both schemes" territory.
Lazy re-encryption for existing data. Because you hold the master key, migration is a normal read-modify-write: read the tag, decrypt with the recorded scheme, re-encrypt with the target scheme, write back the new tag and blob. Do it on the read path (opportunistic) or as a batched backfill; either way the write is the atomic step, so a crash mid-migration leaves a v1 record, not a corrupt one.
Keep factory and encryptor schemes aligned in one place. If you use both the manager API and the low-level encryptors, construct them from one config so a flip is a single change rather than a grep exercise.
Batch ZUC through the encryptor. ZucEngine::keystream(int $length): string is the fast path (~3.55 MB/s end-to-end vs 0.3), and the encryptors already use it. If you drive ZucEngine directly, call keystream() instead of looping step()/nextKey() — the win comes from eliminating the per-16-byte pack and string reallocation, which a manual loop reintroduces. The old methods still exist unchanged if you need streaming/incremental semantics.
Lean on the typed registry. AbstractRegistry now carries @template/@extends, so $registry->get($id) resolves to the concrete type rather than object. Annotate your own registry subclasses with the template parameter and your IDE and PHPStan get real types for free.
hash_hmac($algo, $data, $key) convention anywhere (wrapping the same derivation, a custom macDerivation equivalent), "correcting" it in place breaks compatibility with every v1 record. Treat it as an opt-in switch on your side too.composer update.ext-gmp matters for test parity. The suite reports 260 cases / 4605 assertions, with ~9 skipped locally without ext-gmp; those execute in CI. If your local run looks one shade greener than CI, that's why — install the extension before debugging a phantom discrepancy.scripts/i18n-verify.php checks structural parity with the English mirror (heading depth, code blocks, table rows, separators, images), link/image reachability, TOC anchors, and key sets; --write-en regenerates the English mirror. Run it in CI — it's the thing that catches a whole missing section, which is exactly the failure mode prose review misses.How can I help you explore Laravel packages today?