-
Notifications
You must be signed in to change notification settings - Fork 2
FAQ
Common questions, roughly ordered by how often they come up.
If you have no opinion, Sodium. The construction has no knobs, the defaults are correct, and the cryptography is modern. Pick OpenSSL only if you have a concrete reason: FIPS compliance, custom cipher requirements, or libsodium-isn't-available environments.
See Sodium Handler and OpenSSL Handler.
Three reasons:
-
URL-, cookie-, JSON-safe everywhere without escaping. Base64
needs
base64urlto be URL-safe; hex is URL-safe by default. -
Easier to debug.
02006f1c...immediately tells you "this is a v2 ciphertext, JSON serializer". A base64 string hides the format header. - Cheap to detect tampering at the boundary. Any non-hex character is rejected before any cryptographic work runs.
The cost is a 2× size factor over the raw binary. If you store millions
of ciphertexts and bytes matter, hex2bin() before storage and
bin2hex() again on read — the package's encrypt() / decrypt() only
ever speak hex on the public surface.
Yes — hex is URL-safe. For cookies, set the usual Secure, HttpOnly,
SameSite=Strict flags. Watch for the 4 KB cookie size cap; a
ciphertext is roughly 2 × (header + IV/nonce + HMAC + payload)
characters, so JSON payloads bigger than a few hundred bytes start to
encroach.
See Recipes #1 and Recipes #3.
Because unserialize() on attacker-controlled bytes is the canonical
PHP object-injection vector, and "the bytes are HMAC-verified so the
attacker can't control them" is true only as long as your key never
leaks. JSON cannot instantiate classes — defense in depth.
If your payloads genuinely need PHP's serialization (binary blobs, deep
custom classes), pass 'serializer' => 'php_serialize' explicitly. The
package always invokes unserialize() with ['allowed_classes' => false] in that mode, so you still get a meaningful defense.
See Serialization.
No. There is no "encrypt without authenticate" mode, and there won't be. Authenticated encryption is the only encryption a modern library should offer; the cost is negligible and the safety guarantees are large.
If you have a legitimate need for unauthenticated encryption (you are
streaming gigabytes and want to authenticate the whole stream at the
end), this package is the wrong tool — use openssl_encrypt() directly.
Not in 2.x. Both handlers operate on the full payload in memory.
For large blobs:
- libsodium has
crypto_secretstream_xchacha20poly1305_*, which is the right primitive for streaming AEAD. Build a custom handler around it — see Custom Handlers. - For OpenSSL streaming,
openssl_encrypt/openssl_decryptoperate on full buffers; you would need to useext-openssl's stream filter machinery directly, which is outside the package's scope.
No, that's a feature. OpenSSL uses a fresh random IV per call; Sodium uses a fresh random nonce. If two ciphertexts of the same plaintext were identical, an attacker could deduce that the plaintexts match without ever decrypting either.
If you need deterministic encryption (e.g. for a database equality index), the package is the wrong tool — that requires a separate construction (synthetic IV, FF1, …) with different security properties.
Two processes using the same handler class and the same options will interoperate. Sodium key derivation and OpenSSL HKDF are both deterministic on the user key.
You cannot decrypt an OpenSSL ciphertext with the Sodium handler or vice versa — the wire formats are different. The package's integration test suite asserts this in both directions.
You can't, with the built-in handlers — the cipher and algorithm are not recorded in the wire format. Decryption uses whatever the handler is configured with at decrypt time.
If you want self-describing cipher choice, build a custom handler that embeds a cipher ID in the payload (between the format header and the ciphertext bytes). See the "Versioning Your Own Format" section in Custom Handlers.
Effectively yes. allowed_classes: false means unserialize() returns
__PHP_Incomplete_Class for any custom class rather than instantiating
it — no constructor runs, no __wakeup / __destruct is triggered.
That said, JSON is categorically safer because no class metadata is even parsed. Use JSON unless you have a concrete reason to use serialize.
The Sodium handler zeroes the derived key (the 32 bytes that go into
crypto_secretbox) before returning, but the user key — the one you
passed into the handler's options — lives in your $options array,
which is your buffer to manage.
If you want the user key wiped, manage that buffer yourself:
$key = read_key_from_vault();
$handler = new \InitPHP\Encryption\Sodium(['key' => $key]);
// $handler now has the key inside its options array; that's the buffer
// you'll need to clear if you want it gone. Either trust the GC or
// hold a reference yourself for sodium_memzero().
$ct = $handler->encrypt($payload);For small files (anything that fits in PHP's memory_limit
comfortably) — yes. encrypt(file_get_contents(...)) then
file_put_contents(..., $ct) works fine.
For large files, see "Does the package support streaming encryption?" above. And Recipes #4 for the small-file pattern.
^8.1 means "8.1 or any later 8.x". When 9.0 comes out, this constraint
prevents the package from auto-installing — intentional, since 9.0 will
probably have breaking language changes the package needs to verify
against first. A future 2.x release will widen the constraint.
CHANGELOG.md
at the repository root, in Keep a Changelog
format.
You have ciphertexts produced by 1.x trying to decode under 2.x. This is the deliberate, designed BC break — see Migration from 1.x for the re-encryption recipe.
The package does not implement any PSR interface — there isn't a PSR for symmetric encryption. It does follow:
-
PSR-4 for autoloading (
InitPHP\Encryption\→src/). -
PSR-12 for code style (enforced by
composer cs-checkin CI). - PHPStan level 8 on the entire source tree.
Open a GitHub Discussion in the Q&A category. If the answer is a doc gap, the question ends up answered here in the next release.
initphp/encryption · MIT License · part of the InitPHP family
Source · Issues · Discussions · Packagist · Contributing · Security Policy
Getting Started
Handlers
Reference
Practical Guides
Other