Password7Decrypt

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.

PropertyType 7Type 8Type 9
AlgorithmXOR cipher, static tablePBKDF2-SHA256scrypt
SaltedNoYesYes
ReversibleYes — triviallyNoNo
Resistant to GPU crackingN/A (reversible)ModerateStrong (memory-hard)
Minimum supported IOSEssentially all releases15.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:

grep -E "password (5|7|8|9) " *.cfg | sort | uniq -c

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:

show running-config | include password 7

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.

Tip: Prioritize by exposure once you have the census: internet-facing edge devices and anything reachable from a less-trusted segment (guest VLANs, partner links, anything with SNMP or TFTP exposed) should move first, regardless of how many total devices are on the list.

Step 2: Recover the Plaintext

You have two realistic paths for each password on your list:

⚠️ Important: Recovering a Type 7 password is a good moment to rotate it, not just re-encode the same value under Type 9. If a config has been sitting around long enough to need this migration, it's reasonable to assume that password has been exposed somewhere along the way — a backup email, a ticket, a departed contractor's laptop.

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:

configure terminal
enable algorithm-type scrypt secret NewStrongPassword123!
username admin algorithm-type scrypt secret NewStrongPassword123!
end
write memory

A short walkthrough of what each line does:

CommandPurpose
configure terminalEnters 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
endExits back to privileged EXEC mode
write memorySaves running-config to startup-config — skip this and a reload reverts everything

After saving, confirm the change actually took by reviewing the config again:

show running-config | include secret

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:

show running-config | include enable password

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.

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.

Tip: Roll out in waves, not all at once — start with a low-risk pilot group, confirm nothing breaks (monitoring polls, automation logins, AAA fallback), then expand to the next wave.

Common Pitfalls

Forgetting write memory — a reload silently reverts to the old Type 7 config
Migrating the enable secret but leaving line vty / line con passwords on Type 7
Not checking IOS/IOS-XE version support for the scrypt keyword before scripting a mass rollout — older images will reject the command outright
Re-using the recovered plaintext as the new password instead of rotating to something new
Automating the rollout across devices before validating the process manually on a pilot group
Related reading: Not sure why Type 8/9 count as "real" security while Type 7 doesn't? See Encoding vs. Encryption vs. Hashing. Rolling this out across an entire inherited network? See Auditing Legacy Network Configs and the Cisco Password Security Checklist.