php-encryption
Misuse-resistant authenticated encryption for PHP, with a simple key- or password-based API
Repository Health
Technical Analysis
defuse/php-encryption is a PHP library for encrypting data with a key or a password, built to be secure by default and difficult to misuse. It wraps AES-256-CBC with an HMAC in an authenticated-encryption scheme, exposing a small set of static methods (Crypto::encrypt, Crypto::decrypt, and password variants) so developers never have to choose ciphers, modes, or padding themselves.
Maintained jointly by Taylor Hornby and Scott Arciszewski (of Paragon Initiative Enterprises, the maintainers of libsodium’s PHP bindings), the library targets applications that need to encrypt data at rest on the server. It bundles constant-time comparison and a CSPRNG-backed random source so common cryptographic pitfalls — ECB mode, unauthenticated ciphertext, timing attacks — are avoided by construction rather than left to the caller.
What You Get
- Crypto class with static encrypt/decrypt methods for both raw keys and passwords
- Key and KeyProtectedByPassword classes for generating and storing encryption keys
- File class for streaming encryption/decryption of large files without loading them fully into memory
- Authenticated encryption (encrypt-then-MAC) that rejects tampered ciphertext instead of silently returning garbage
- Constant-time comparison utilities to avoid timing side-channels
Common Use Cases
- Encrypting sensitive database columns (PII, tokens, secrets) before storage
- Encrypting session data or cookies that must not be readable or forgeable by the client
- Encrypting files at rest on a server (backups, uploads containing sensitive data)
- Building password-protected secrets/config vaults inside a PHP application
Under The Hood
Architecture - The library centers on src/Crypto.php, a stateless class of static methods (encrypt, decrypt, encryptWithPassword, decryptWithPassword) that orchestrate lower-level primitives in Core.php (raw HMAC/cipher operations), Key.php and KeyProtectedByPassword.php (key material handling), and KeyOrPassword.php (a small internal abstraction that normalizes both key sources into one derivation path). File.php mirrors the same encrypt/decrypt flow but streams data in fixed-size blocks through fopen handles so large files never load fully into memory. Every failure path throws a typed exception from src/Exception/, so callers get explicit EnvironmentIsBrokenException/WrongKeyOrModifiedCiphertextException errors instead of silent corruption. Tech Stack - Pure PHP with no runtime dependencies beyond the ext-openssl extension and the (bundled) paragonie/random_compat polyfill for older PHP versions; PHPUnit (versions 5 through 10, selected via separate phpunit-*.xml configs) is used for tests, and psalm.xml wires up static analysis. Code Quality - The test/unit suite covers encryption round-trips, tampered-ciphertext rejection, and edge cases like empty strings and wrong-key decryption; public methods perform explicit TypeError-throwing argument checks (e.g. verifying $key instanceof Key) rather than relying on PHP’s loose typing, and PHPDoc blocks document parameter and exception contracts throughout. API Design - The public surface is intentionally minimal — one class, a handful of static methods, two key types — which keeps the “pit of success” narrow: there is no cipher or mode parameter to get wrong, and the Tutorial/FAQ docs in docs/ walk through the two supported flows (key-based and password-based) end to end.