Migrating from Type 7 to Type 9
A complete, phased process for retiring Cisco's weak Type 7 password encryption in favor of Type 9 (scrypt) — across a handful of devices or an entire estate — without locking yourself out along the way.
Why This Migration Matters
Type 7 has been reversible with nothing more than a public, well-known XOR lookup table since it was introduced. If an attacker gets read access to a config file — through a misconfigured TFTP server, a leaked backup, a compromised jump host, an exposed Git repo, or simply an unattended laptop — every Type 7 password in that file is effectively plaintext within seconds. Our own Type 7 decoder demonstrates this: there's no secret involved, just publicly documented math.
Type 9, available on newer IOS and IOS-XE releases, replaces this with scrypt: a salted, memory-hard hashing algorithm. Unlike Type 7, it cannot be reversed — not with more compute, not with the algorithm in hand, not ever. The only way to "recover" a Type 9 password is to reset it, because the whole design goal of a hash is one-way transformation.
The catch, and the reason this migration gets postponed for years at some organizations: you can't just "upgrade" an existing Type 7 hash to Type 9 in place. Type 9 needs the original plaintext to generate a valid hash, and Type 7 needs to be decoded to get that plaintext in the first place. That's the actual technical dependency this whole guide is built around.
| Property | Type 7 | Type 8 | Type 9 |
|---|---|---|---|
| Algorithm | XOR cipher, static table | PBKDF2-SHA256 | scrypt |
| Salted | No | Yes | Yes |
| Reversible | Yes — trivially | No | No |
| Resistant to GPU cracking | N/A (reversible) | Moderate | Strong (memory-hard) |
| Minimum supported IOS | Essentially all releases | 15.3(3)M+ / IOS-XE 16.3+ | 15.3(3)M+ / IOS-XE 16.3+ |
Step 1: Inventory What You Actually Have
Before touching a single device, get a current-state picture across the whole estate. Don't rely on old documentation — pull a fresh backup of every reachable device's running-config (and startup-config too; the two drift more often than people expect).
Scanning backups from your workstation, not the Cisco CLI
Once you have a folder of config backups sitting on your own machine (or a backup/jump server), you can scan all of them at once with a standard Linux/macOS shell command — this is not a Cisco IOS command, it runs in your regular terminal against the downloaded text files:
This gives a rough census in one pass: how many lines are still Type 7, how many are on the deprecated Type 5 (MD5), and how many are already Type 8/9. If your backups use a different extension (.txt, .conf), just adjust the glob pattern accordingly, e.g. *.txt.
If you'd rather check one device directly over SSH
This part does run on the Cisco device itself, from the IOS CLI:
Use this for a quick one-off check; use the workstation-side grep approach above when you need to sweep dozens or hundreds of backup files at once — logging into every device individually doesn't scale.
Step 2: Recover the Plaintext
You have two realistic paths for each password on your list:
- You already know it. If it's a shared team credential that's properly documented (in a password manager, ideally — not a spreadsheet or wiki page), just use that known value directly to generate the new hash. No decoding needed.
- You don't know it, but it's Type 7. Because Type 7 is reversible by design, decode it with a trusted, browser-local tool (see our Type 7 decoder — nothing is sent to a server) to recover the plaintext.
Step 3: Generate the Type 9 Hash on the Device
On a supported IOS-XE release, let the device generate the hash for you rather than hand-computing scrypt output — this is the safest and most common approach. Run each of these as its own command at the IOS CLI, in order:
A short walkthrough of what each line does:
| Command | Purpose |
|---|---|
configure terminal | Enters global configuration mode |
enable algorithm-type scrypt secret ... | Sets the privileged-mode enable secret, hashed with scrypt (Type 9) |
username admin algorithm-type scrypt secret ... | Sets (or updates) a local user account with a scrypt-hashed secret |
end | Exits back to privileged EXEC mode |
write memory | Saves running-config to startup-config — skip this and a reload reverts everything |
After saving, confirm the change actually took by reviewing the config again:
You should now see a line beginning with secret 9 $9$... rather than password 7 .... Also confirm the old enable password line is fully removed with:
IOS will honor enable secret over a co-existing enable password, so functionally you're already protected once the secret is set — but leaving the weak line in the config is still unnecessary exposure, and it will trip most compliance scanners looking for Type 7 strings regardless of which one IOS actually uses.
Step 4: Test Before You Move to the Next Device
Before closing out a device as "done," actually log out and log back in with the new credential — over console, not just SSH. Console access is the fallback path during an incident, and discovering a typo in your migration script there, during an actual outage, is the worst possible time.
- Test the new enable secret from a fresh session, not one that's already privileged.
- Test the local username/secret pair specifically if it's used as an AAA fallback method.
- Keep a saved copy of the prior config (from Step 1's backup) until access is confirmed working, so you have a documented rollback path.
Step 5: Scale It Across the Estate
Once the process is validated on a handful of devices, the same steps can be pushed through automation rather than typed manually device-by-device. Tools like Ansible's ios_config module, Nornir, or a simple expect/paramiko script can apply the same three configuration lines across a batch of devices from your inventory — but only after you've already recovered and rotated the plaintext for each one individually. Automation speeds up applying the change; it doesn't remove the need to handle each password's recovery and rotation carefully.
Common Pitfalls
write memory — a reload silently reverts to the old Type 7 config
line vty / line con passwords on Type 7
scrypt keyword before scripting a mass rollout — older images will reject the command outright