What is the Magento crypt-key?
Short answer
The Magento crypt key is the secret key in app/etc/env.php under crypt → key. Magento’s Encryptor uses it to encrypt secrets before they go into the database, such as payment gateway passwords and API keys saved in config fields that use the Magento\Config\Model\Config\Backend\Encrypted backend model. It also signs the JWT admin and customer API tokens in 2.4.x. Since 2.3 the cipher is ChaCha20-Poly1305 through libsodium. You rotate it with bin/magento encryption:key:change. I treat it like the database password: lose it and every encrypted value has to be re-entered by hand.
- The installer generates a random key 01
- Application code encrypts on write 02
- Application code decrypts on read 03
- Rotation via bin/magento encryption:key:change 04
- Secrets management, never commit env.php 05
Most common mistake Committing env.php to git
Five steps from key generation to rotation in production
There is nothing mysterious about the crypt key. It is one value in env.php and one framework class that uses it. This is the path from install to rotation.
-
01
The installer generates a random key
During
bin/magento setup:installMagento generates a random key and writes it toapp/etc/env.phpas'crypt' => ['key' => '...']. You can also pass your own with--key. After a rotation the samekeyvalue holds several keys, one per line, oldest first and newest last. Magento always encrypts with the last one. -
02
Application code encrypts on write
When Magento saves a secret, for example a payment gateway password in
core_config_data, it callsMagento\Framework\Encryption\EncryptorInterface::encrypt(). The encryptor takes the newest key, encrypts with ChaCha20-Poly1305 through libsodium, base64-encodes the result and puts a prefix in front such as1:3:. The first number is the key version (which line incrypt/key), the second is the cipher version. That prefix is what you see when you look at an encrypted config value in the database. -
03
Application code decrypts on read
decrypt()reads that prefix, picks the matching key line and cipher, and decrypts. If that key is no longer inenv.phpthe value comes back empty and cannot be recovered. I see this most often when someone restores a production database onto a server with a differentenv.php, or deletes the "old" key lines to tidy up. Payment and shipping API credentials suddenly stop working, with nothing obvious in the logs. -
04
Rotation via
bin/magento encryption:key:changebin/magento encryption:key:changeadds a new key line tocrypt/keyand re-encrypts the values Magento knows about, such as encrypted rows incore_config_data, with the new key. The old lines stay inenv.phpso anything not re-encrypted (third-party module columns, older backups) can still be read. Before I run it on a live store I take a database backup and a copy ofenv.php, and afterwards I check that payment and shipping methods still connect. -
05
Secrets management, never commit env.php
app/etc/env.phpis in Magento’s default.gitignorefor good reason: it holds the crypt key, the database password and the admin path. On my deployments it lives only on the server or comes from a secrets store at deploy time, never from git or a container image. I also keep a copy of the key in a password manager. Loseenv.phpwith no copy of the key and every encrypted config value has to be entered again by hand.
Four moments when rotating the crypt-key is the obvious move
Rotating the key takes a few minutes if you plan it. These are the four moments when I tell a client to do it.
-
On a new install, check the key is unique
Right after
bin/magento setup:installI openapp/etc/env.phpand check thatcrypt/keyis a long random value, not a placeholder, not blank, and not copied from another project. Install scripts and Docker templates sometimes pass the same--keyto every environment. If production shares a key with staging or a public template, rotate it withbin/magento encryption:key:changebefore you enter any real API credentials. -
After personnel change or suspected env.php leak
Anyone who has had read access to
app/etc/env.phpmay still have the key on a laptop or in an old backup. When a developer or agency leaves the project, a laptop goes missing, orenv.phpgets pasted into a chat by mistake, I rotate the key withbin/magento encryption:key:change. New values are then encrypted with a key they never saw. I also change the database password and any API credentials they could have read, because rotating the key does not change those. -
After upgrading an old store with legacy ciphertext
Stores that started on Magento 2.0 to 2.2 can still hold values encrypted with the old mcrypt-era ciphers. Those still decrypt, because the cipher version sits in the prefix, but they are not on the current libsodium cipher. After moving such a store to 2.4.x I rotate the key so config values are written again with the current cipher, and I run
bin/magento encryption:payment-data:updatefor stored payment data. -
After a breach or PCI-DSS incident
This is the case Adobe pushed hard in 2024 after CosmicSting (CVE-2024-34102), where attackers could read
env.phpand forge admin API tokens with the key. If a server is compromised or a backup leaks, I rotate the key so new tokens and new encrypted values use a key the attacker does not have. Rotation does not protect secrets that were already stolen, so I also change the payment, shipping and API credentials at the provider, reset admin passwords and remove unknown integrations.
Three crypt-key mistakes that wreck a Magento store
Every crypt-key emergency I’ve been called in to triage came from one of these three mistakes. Audit your repo, your backup pipeline, and your rotation runbook before you need them.
-
Committing
env.phpto gitThe single most common Magento security leak.
app/etc/env.phpholds the crypt-key, the DB password, the admin frontname, and the session config, one accidentalgit add app/etcand the whole site is exposed in the git history forever, even after a delete commit. Always confirmenv.phpis listed in.gitignore(it is, by default, in fresh installs, but custom.gitignorerewrites often miss it). Commit a sampleenv.php.exampleonly. If you discover env.php in git history, ROTATE the crypt-key immediately and rewrite the git history withgit filter-repo. -
Restoring a DB dump without the matching
crypt.keyWhen you copy a production DB dump down to staging, the ciphertext in
vault_payment_token,oauth_token, and encrypted rows ofcore_config_dataall expect to be decrypted with the production crypt-key. Restoring the dump onto a fresh Magento install with its own auto-generated crypt-key turns every encrypted column into garbage, saved-payment-tokens silently fail at checkout, API integrations 401, and encrypted config fields decrypt to noise. The crypt-key MUST travel alongside any DB dump. If you forgot, the only fix is to clearvault_payment_token, regenerate API integrations, and re-enter every encrypted config value via admin. -
Running
encryption:key:changeon a live store without maintenance modeThe rotation walks every encrypted column in the database and can take several minutes on a large store. Any concurrent vault-token-save or admin config-save during that walk can end up encrypted with one key but pointing at another via the version marker, leaving permanently-broken rows that no key in
env.phpcan decrypt. Always wrap the rotation inbin/magento maintenance:enablefirst, run the rotation, verify a few decrypts work, thenmaintenance:disable. On a CI/CD pipeline this is a release-window job, not a hot-fix.
Magento crypt-key: frequently asked questions
-
Can I change the crypt-key manually by editing
env.php?No, never. The crypt-key inenv.phpis the symmetric key Magento uses to decrypt every encrypted DB column (saved-payment-tokens, OAuth tokens, integration secrets, encryptedcore_config_datarows). If you swap the value inenv.phpwithout re-encrypting the DB, every existing ciphertext becomes permanently undecryptable, the version marker on each ciphertext (0_:,1_:) points at a key index that no longer matches the actual value. The correct path is alwaysbin/magento maintenance:enablefollowed bybin/magento encryption:key:change, which atomically generates the new key, walks every encrypted column, and re-encrypts each row with the new key while keeping the old key in the array as a fallback. -
What happens if I’ve lost the original crypt-key?
Every saved payment token, OAuth/API credential, and encrypted config field that was encrypted with the lost key is permanently unrecoverable, AES-256 is unbreakable in practice without the key. The practical recovery path is: 1) clearvault_payment_token(customers will re-enter cards on next checkout), 2) regenerate every API integration in admin (Stores → Integrations) so external systems re-pair, 3) re-enter every encrypted config field manually in admin (payment-gateway credentials, SMTP passwords, third-party API keys flagged withbackend_model="Magento\Config\Model\Config\Backend\Encrypted"). Then generate a fresh strong crypt-key by runningbin/magento encryption:key:change, even though there’s nothing left to re-encrypt, the command writes the new key cleanly. Document the new key in your password manager immediately. -
Does the crypt-key rotation require downtime?
For any production store, yes, always run in maintenance mode.bin/magento encryption:key:changewalks every encrypted column in the database, and on a large store with hundreds of thousands of saved-payment-tokens or many encrypted config rows the walk can take several minutes. Any concurrent write during the walk, a customer saving a new card, an admin saving a config field, an API call provisioning a token, can end up encrypted with one key but with a version marker pointing at another, leaving a permanently-broken row. The safe sequence is:bin/magento maintenance:enable, then the rotation, then a spot-check decrypt on a sample of the rotated rows, thenmaintenance:disable. Schedule it inside a release window, not as a hot-fix. -
How long should the crypt-key be?
Magento generates a 256-bit (32-byte) key by default, encoded as 64 hex characters, equal to the AES-256 key length. Do not shorten it. Do not replace it with an ASCII phrase. Do not derive it from anything memorable. The right way to generate a replacement value, if you ever need to seed one beforeencryption:key:changerebuilds it, isopenssl rand -hex 32, which produces exactly the 64-hex-char format Magento expects. AES-256 with a properly random 256-bit key has no known practical attack; the only way the encryption becomes weak is if the key itself is short, predictable, or leaked. -
Is the crypt-key the same as Magento’s password hash salt?
No, completely separate systems. Customer and admin passwords are hashed with a one-way function (bcrypt or argon2 in modern Magento) using a per-row random salt that is stored in the same column as the hash. That hash is one-way: Magento can verify a password at login by re-hashing the input, but it cannot reverse the hash to retrieve the original password, the crypt-key is not involved at all. The crypt-key, by contrast, is for two-way encryption of secrets the application needs to read back and use, payment-method tokens get re-sent to the PSP, API credentials get re-sent to third-party systems, encrypted config values get decrypted at runtime. Rotating the crypt-key does not invalidate any password; rotating passwords does not affect the crypt-key. -
How do I check if my crypt-key is the Adobe Commerce Cloud default weak key?
Openapp/etc/env.phpand copy the value ofcrypt.key. Compare against any known-bad hashes documented in the relevant Magento Security Bulletin (Adobe publishes these athelpx.adobe.com/security). If it matches a published weak key, rotate immediately. As a defence-in-depth measure even if it does not match, on any store inherited from a previous developer or a managed-hosting provider, just rotate,bin/magento maintenance:enable && bin/magento encryption:key:change && bin/magento maintenance:disable. The rotation is cheap, the cost of running on a leaked key is potentially catastrophic. Pair the rotation with rotating the DB password and admin passwords for full key-hygiene on the inherited install.
Want a crypt-key + env.php audit on your Magento store?
Send your storefront URL, I will check your env.php hygiene, crypt-key strength, rotation history, encrypted-column health, and backup-of-key procedure, then reply with a written hardening plan, fixed-price quote, and earliest start date. 24-business-hour turnaround.