Skip to content

33 β€” Password, Crypto and Secrets Tools

Level: Intermediate Β· Time: ~20 min Β· Prerequisites: Lesson 32 β€” Host Security and Audit Tools


Why this matters

Almost every incident starts with a credential. Not a clever exploit β€” a password that was reused, a token left in a repository, a key that never expired, an internal service still offering a protocol from 2009. The tools in this lesson are how you find out whether your own credentials would survive contact with an attacker, how you check that the cryptography you depend on is actually doing its job, and how you stop secrets from living in places where everyone can read them. Used on your own systems, they are the cheapest risk reduction available to a small team.


The mental model: one family per question

The question The tool What it tells you
Would this password survive a real cracking attempt? hashcat or John the Ripper, against a hash from your own lab how many minutes of GPU time your policy buys
Is this service's certificate valid, and until when? openssl s_client and openssl x509 expiry, issuer, the names it covers, chain completeness
Does this service still accept an obsolete TLS version? openssl s_client with an explicit protocol version a real, common and easily fixed finding
Is this download the file I think it is? sha256sum plus a signature integrity, and authenticity if signed
Where are the humans' passwords? a password manager: local file, or self-hosted for a team unique passwords and a single strong passphrase
Where are the machines' secrets? encrypted secrets files with the key delivered separately, or a secrets server no credentials in code, config or chat

[!IMPORTANT] Password cracking tools test your own hashes, from your own systems, with written authorisation. A cracking rig plus a hash database you did not create is a criminal combination, and running these tools against a corporate system without a signed scope is how careers end. Everything below assumes your lab, your credentials, your rules.


Cracking your own hashes to prove a policy

First, understand which game you are playing. Online guessing is limited by the service; offline cracking is limited only by your hardware.

Online guessing Offline cracking
Where the work happens against a live login on your hardware, against a file of hashes
Speed limit rate limits, lockouts, MFA whatever your GPU can do
Visible to you? yes, in your authentication logs no β€” and the breach already happened when the dump was taken
What it needs a network path and a list of accounts the hashes
What defends it lockouts, MFA, distributed-failure alerting hash strength, password length, and not losing the dump

Two open-source crackers cover the ground. hashcat is GPU-first with a very large catalogue of hash modes and two strong attack engines: wordlists with mangling rules, and masks for passwords of a known shape. John the Ripper (the community "jumbo" build) is excellent on the CPU and supports an enormous range of formats, including old and unusual ones. When both support the format, prefer hashcat for speed; reach for John when the hash is exotic.

# Wordlist plus bundled mangling rules β€” the realistic-attack default
hashcat -m 1000 -a 0 ntlm.txt /usr/share/wordlists/rockyou.txt \
        -r /usr/share/hashcat/rules/best64.rule
hashcat -m 1000 ntlm.txt --show          # what has been recovered so far
hashcat -b                               # benchmark: know your own rate before quoting numbers

# Mask attack: uppercase, lowercase, digits, of a length you observed
hashcat -m 0 -a 3 md5.txt ?u?l?l?l?l?d?d

john --format=nt --wordlist=rockyou.txt --rules=Jumbo ntlm.txt
john --show --format=nt ntlm.txt
Flag Meaning
-m 1000 hash mode. 0 is raw MD5, 1000 is NTLM, 1800 is SHA-512 crypt, 3200 is bcrypt, 22000 is WPA
-a 0 / -a 3 / -a 6 attack mode: wordlist / mask / hybrid wordlist plus mask
-r file.rule apply mangling rules (password becomes P@ssw0rd1, Password2026, and so on)
--show, -o, --runtime read results back, write them out, bound the run
--format, --incremental, --fork John's equivalents: hash type, expanding search, parallel processes

The reason this matters is that wordlist plus rules is not brute force. A hundred million realistic variants of human-chosen passwords will beat an astronomically large search that never finishes. The payoff of running it in your lab is a number you can take to management: at our current minimum length, a stolen database gives an attacker the average user's password in under a day.

Now the defence, and why some hashes are boring to crack:

  • A salt (random data stored with each hash) makes precomputed tables useless and forces cracking to be done per account. Two users with the same password no longer share a hash.
  • Deliberately slow functions β€” bcrypt, scrypt, Argon2 β€” are tunable: they attach a cost parameter (iterations, memory, or both) so each guess takes real time. Cracking them still works, but the rate collapses from billions of guesses a second to thousands, and the honest-looking difference between a two-hour crack and a two-century one is the whole argument.
  • Length multiplies work. Every added character multiplies the search space; a trailing ! is predicted by every rule set in existence.

So the policy changes these tools justify: raise the minimum length to something a person needs a phrase for, screen new passwords against known-breached lists (a service can do this without ever seeing the password, by sending only a short prefix of the hash), drop forced composition and arbitrary expiry rules in favour of length and screening, and put MFA and a password manager behind it. The current NIST digital identity guidance (SP 800-63B) says the same thing β€” length and breach screening over composition rules β€” and it is the standard your auditor or insurer is most likely to accept.


Certificates and TLS with the crypto command-line toolkit

openssl is the multi-tool you already have. Five jobs cover most of the work.

# 1. Create a private key and a certificate signing request
openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:2048 -out server.key
openssl req -new -key server.key -out server.csr -subj "/CN=web.example.com"

# 2. Read what is actually in a certificate
openssl x509 -in server.crt -noout -subject -issuer -dates

# 3. Inspect a live service: chain, names, dates
echo | openssl s_client -connect www.example.com:443 -servername www.example.com 2>/dev/null \
  | openssl x509 -noout -subject -issuer -dates

# 4. Expiry across a list of hosts β€” the five-minute monthly check
for h in mail.example.com www.example.com vpn.example.com; do
  printf '%-24s ' "$h"
  echo | openssl s_client -connect "$h:443" -servername "$h" 2>/dev/null | openssl x509 -noout -enddate
done

# 5. Does this service still accept an obsolete protocol version?
echo | openssl s_client -connect www.example.com:443 -tls1_1 2>&1 | grep -E 'Protocol|alert'

-servername sends the SNI name, which is required whenever several sites share an address, and 2>/dev/null discards the handshake detail you asked not to see. In check 5, a completed handshake is the finding: if the connection succeeds and the negotiated protocol line shows the old version, the service still offers it and a client can negotiate down to it. Remove old versions from the server configuration and re-test until only the current ones answer. nmap --script ssl-enum-ciphers -p 443 host from Lesson 30 does the same job across a range of hosts and lists the accepted ciphers with a strength grade.

What to check, and what each answer means:

Read four things in every certificate: the subject and subject alternative names (does it cover the name clients actually use?), the issuer and the chain sent with it (from a CA you expect, with the intermediates clients need?), the date range (expiry, and whether a long-lived service has a suspiciously new certificate), and the key size and signature algorithm (anything older than your policy allows?). openssl verify -CAfile ca.pem server.crt checks your own internal chain end to end. An expired certificate is an outage, a self-signed one on an internal service is a routine finding, and a certificate from a public CA for an internal name is either a mistake or a sign somebody is intercepting your traffic.


Hashing, encryption and signing in daily use

Integrity first, because it is the boring half that everything else depends on:

sha256sum image.iso            # compute; Get-FileHash -Algorithm SHA256 on Windows
sha256sum -c SHA256SUMS        # verify a published list of checksums
cmp file1 file2                # byte-for-byte comparison of two files

MD5 and SHA-1 are broken for security purposes β€” do not use them for anything that matters, and treat a published MD5 as an integrity hint rather than a guarantee. A checksum also proves nothing about who published the file: an attacker who can change the file can change the checksum beside it. That is what signatures are for.

# Symmetric: one passphrase, and the same one to decrypt
gpg --symmetric --cipher-algo AES256 backup.tar.gz
gpg --decrypt backup.tar.gz.gpg > backup.tar.gz

# Keypair: encrypt to a recipient's public key, sign with your private one
gpg --encrypt --recipient colleague@example.com report.pdf
gpg --detach-sign --armor release.tar.gz          # a signature file alongside the artefact
gpg --verify release.tar.gz.asc release.tar.gz

GPG and age are the two common open-source tools. age is deliberately simpler: one short key file, one command, no web of trust, which is why it has become the default for encrypting files and backups. Symmetric encryption is the right choice when you are the only person who needs to read the file (encrypting a backup before it leaves your control); keypair encryption is the right choice when you are sending to someone else, and it is the only shape that can prove authorship, because signing uses a private key only the author has.

Job Approach
Encrypt a backup before it leaves your control age -r <public key> -o backup.age backup.tar.gz, private key stored separately
Send a sensitive file to a colleague encrypt to their public key, or to a shared team key stored in your password manager
Verify a downloaded installer is genuine check the publisher's signature, not just the checksum

Password managers, secrets and SSH keys

A password manager is the single most effective personal security control, because it makes unique passwords per service the easy option rather than the disciplined one. Two models, and you can use both:

Model Examples Trade-off
Local file-based KeePassXC (.kdbx file, optional key file) nothing to host, no cloud dependency; you must sync and back up the file yourself
Self-hosted server Vaultwarden with compatible clients, or Passbolt for team sharing shared vaults with an audit trail and per-user access; you must run, patch and back up the server

Run one for the team and set the rules: the manager's own account has MFA, shared credentials live in a shared vault (never in chat or a spreadsheet), everyone can see who has access, and the vault is backed up somewhere you can restore from. Losing the vault without a backup is an incident of its own.

Secrets management is the same discipline for machines. The problem: credentials in code, in configuration files, in chat, in a shared spreadsheet, and in the CI logs nobody reads. The practices are not complicated:

  • Separate development from production β€” different credentials, different scope, different storage.
  • Never commit a secret. Add a scanner to your workflow (gitleaks detect --source . on a repository, and a staged-changes check before commit) so a mistake becomes a failed build rather than a disclosure.
  • Rotate on a schedule and immediately on suspicion β€” including every credential the suspect host could have read.
  • Prefer short-lived credentials where the platform supports them: instance roles rather than long-lived keys, dynamically issued database credentials, tokens with an expiry.
  • Encrypt at rest with the key delivered separately. An encrypted secrets file (for example with SOPS, using age or GPG, or an Ansible vault file for the labs later in this course) is safe to keep in version control only because the key is not with it. A secrets server goes further: it stores them, issues them, and logs who read what.

SSH key hygiene, in one table:

Practice How
Generate a modern key with a passphrase ssh-keygen -t ed25519 -a 100 -C "laptop 2026"
Add a passphrase to an existing key ssh-keygen -p -f ~/.ssh/id_ed25519
No world- or group-readable key files find ~/.ssh -type f -perm /077 should return nothing
Server refuses passwords and root logins sudo sshd -T \| grep -Ei 'passwordauth\|permitrootlogin\|pubkey'
Remove what nobody uses one key per device, a comment naming the device, and unused authorized_keys entries deleted

[!TIP] Rotating one credential is rarely enough. When a host is compromised, rotate everything it could have read β€” service accounts, database passwords, API tokens, deployment keys β€” because you know it had access and you do not know what it copied.


The secrets-hygiene checklist

  1. Every credential has an owner and a documented location β€” no credentials in chat, tickets, spreadsheets or code.
  2. A secret scanner runs before commits, and a finding blocks the change.
  3. Development and production never share credentials or scope.
  4. Rotation is scheduled, and immediate on any suspicion, including everything a suspect host could read.
  5. Long-lived static credentials are replaced by short-lived ones wherever the platform allows.
  6. MFA protects every account that can reach production, with phishing-resistant factors for administrators.
  7. Humans use a password manager; machines use an encrypted secrets store with the key delivered separately.
  8. SSH has one passphrase-protected key per device, password authentication switched off, and no orphan keys.

Why this matters more than the tooling: leaked credentials are found by machines, not people. Automated scanners watch public source repositories continuously, including the history of a repository, branches that were deleted, and forks nobody remembers. Secrets also escape through container image layers (a token in a layer survives its removal from the final image), mobile app bundles that can be unpacked in minutes, build and CI logs, job postings with a convenient example configuration, screenshots in documentation, and paste sites and breach dumps where a 2019 leak is still searchable today. So "it was in a private repository" is not a defence: it is one mis-click, one over-permissive collaborator or one compromised developer account away from being public, and the history is already cloned onto every laptop that ever pulled it. Treat anything that has ever been committed, logged or shipped as disclosed.


Attack it / Defend it

The attack How it works The control that stops it
Password spraying one common password against many accounts MFA, banned-password lists, alerting on distributed failures
Credential stuffing passwords leaked from another breach, reused by your staff MFA, breach screening at password change, a manager that prevents reuse
Offline cracking of a stolen dump crack the hashes at leisure slow salted hashing, long passphrases, and preventing the dump
Secrets harvested from a public repository automated scanning of commits, history and forks pre-commit scanning, rotation on exposure, short-lived credentials, never committing the key
Token stolen from a container image read a credential out of a published layer build-time secret scanning, build args and multi-stage builds that exclude secrets, rotation
Man-in-the-middle against a badly configured service negotiate an obsolete protocol version or a weak cipher disable old protocol versions, test with s_client and cipher scanning, HSTS
Forged or tampered download replace an installer and its checksum signed releases verified with GPG or age keys, signature checked before execution
Reused or orphaned SSH key use an old key left in authorized_keys one key per device, passphrases, password authentication off, periodic key review

Key takeaways

  • These tools exist to test your own systems. Authorisation is the boundary between a security audit and a crime.
  • Wordlist plus rules beats brute force, and running it in your lab produces the one number that changes policy: how long your users' passwords survive.
  • Salt and slow hashing are why "the hashes were strong" is a real answer β€” strength here means an attacker's cost, not secrecy.
  • A checksum proves integrity, a signature proves origin. Only one of them survives an attacker who can edit the file.
  • Treat anything ever committed, logged or shipped as disclosed β€” and rotate on suspicion, not on certainty.

Check yourself

  1. You crack your own NTLM dump in two hours with a bundled rules file. Name the three policy changes that would make the same dump useless next year.
  2. What does a salt prevent, and what does a slow hashing function prevent that a salt does not?
  3. A host still completes a TLS 1.1 handshake. Why is that a finding, and how do you test it from the command line?
  4. A colleague sends you a file and a .asc signature. What does verifying it actually prove, and what does a checksum alone fail to prove?
  5. Your team stores the production database password in a private repository, arguing nobody outside can see it. Give three ways it could still escape.

Next

Lesson 34 β€” Network Defence Tools