Skip to content
All tools
Classical cryptoRuns locallyNo account

Vigenere cipher solver with automatic key recovery

Decrypt Vigenere with a known key, or recover the key from ciphertext alone using index-of-coincidence period detection and per-column chi-squared.

Open in ctfpal

Vigenere applies a different Caesar shift to each position, cycling through a keyword. That defeats plain frequency analysis, because E no longer maps to a single letter. It does not defeat frequency analysis applied per key position, and that two-step insight is the entire attack.

Step one: find the key length

The index of coincidence measures how likely two randomly chosen letters of a text are to be identical. English sits near 0.067; uniformly random text sits near 0.038. Slice the ciphertext into every Nth character for N = 1, 2, 3, ... and compute the IoC of each slice. When N equals the key length, every slice is a plain Caesar shift of English and the IoC jumps back toward 0.067. That spike is your period.

Assumed periodMean IoC of slicesReading
10.041Not monoalphabetic
20.042No
30.043No
40.066Key length 4 - or a multiple of it
80.067Multiples spike too; take the smallest
The IoC of a real Vigenere ciphertext at each candidate period.

Step two: solve each column

Once the period is known, character positions 0, 4, 8, ... all share one shift. That slice is a Caesar cipher, so chi-squared gives its shift directly, and the winning shift for each column is the corresponding letter of the key. Concatenate the columns and you have recovered the keyword without ever guessing it.

Both steps degrade with short ciphertext. Below roughly 100 characters the IoC is noisy and the per-column statistics have too few samples. When automatic recovery fails on a short text, fall back to a crib: if you know the plaintext contains picoCTF, XOR-style crib dragging recovers key fragments directly.

Worked example

Key recovered from ciphertext alone

Input

LXFOPVEFRNHR

Result

ATTACKATDAWN (key: LEMON)

The textbook example. Short, so recovery leans on the crib rather than pure statistics.

Load this example in the workspace

Common questions

How much ciphertext do I need to recover a Vigenere key?
Roughly 20 characters per key letter is a comfortable minimum. A 5-letter key wants 100+ characters of ciphertext; below that the per-column chi-squared has too few samples and will pick wrong letters.
What if the key is as long as the message?
Then it is a one-time pad and statistics cannot help. If the same long key was reused across two messages, that is the many-time-pad situation - use [crib dragging](/tools/crib-drag) instead.

Part of a module

2. Classical ciphers and frequency analysis

Break Caesar, Vigenere, and arbitrary substitution using letter statistics - and learn why statistics beat guessing.

Practise on real challenges

Go deeper

Related tools