Keyword substitution cipher
With the keyword CRYPTO, Hello World becomes Btggj Vjmgp: the keyword opens the cipher alphabet, the remaining letters follow in order, and each letter is swapped for its partner. Decrypt with the same keyword to get the message back. Free in your browser.
- Free
- Runs in your browser
- No sign-up
- Your data stays on your device
Run — free
Worked example
- Text
- Hello World
- Keyword
- CRYPTO
- Action
- Encrypt
- Result
- Btggj Vjmgp
- Alphabet
- CRYPTOABDEFGHIJKLMNQSUVWXZ
- Letters mapped
- 10
Need a classic keyword cipher for classroom demos, puzzle design, CTF warm-ups or reversible obfuscation of short notes? Enter your message and a keyword of unique A–Z letters. The tool builds a mixed alphabet by placing the keyword first and filling the remaining letters in order, then substitutes each letter while preserving case and leaving punctuation, spaces and digits untouched. Choose encrypt or decrypt with the same keyword so round-trips stay exact.
How a keyword substitution alphabet is built
A monoalphabetic substitution cipher replaces every letter of the alphabet with exactly one other letter and keeps that mapping fixed for the whole message. When the mapping is seeded by a keyword, the keyword letters appear first in the cipher alphabet (each letter only once), and the leftover letters of A through Z follow in their natural order. For example, the keyword CRYPTO yields the twenty-six character alphabet CRYPTOABDEFGHIJKLMNQSUVWXZ.
Plaintext A maps to C, B maps to R, C maps to Y, and so on through Z. Decryption inverts the same table: every ciphertext letter is looked up in the mixed alphabet and replaced by the plain letter at the same index. Non-letter characters never enter the map; they are copied through so dates, codes and punctuation stay readable.
Because the keyword must use each letter at most once, the construction is unambiguous: there is no silent de-duplication that could surprise a student comparing hand-built tables with machine output. Uppercase and lowercase forms of the same letter share one map entry; the engine preserves the case of each source character so HELLO and hello encrypt consistently relative to the same alphabet. This classic construction is weaker than modern cryptography and is intended for teaching, puzzles and light obfuscation, not for protecting secrets at rest or in transit.
Encrypt, decrypt and validate the keyword
Send a required text string and a required keyword, and optionally set action to encrypt or decrypt (encrypt is the default). The keyword is trimmed and must contain only letters A through Z with no spaces, digits or symbols. Encrypt walks plaintext letters through the plain alphabet into the mixed alphabet; decrypt walks the opposite direction.
Round-tripping encrypt then decrypt with the same keyword restores the original letter casing and non-letter characters exactly. Status is beta while the public surface stabilizes, but the substitution rules follow this fixed classical construction and will not change for identical inputs.
Practical tips for keyword ciphers
Call the capability with text and keyword as required fields. Use action decrypt when the text is already ciphertext produced by this same keyword alphabet. Prefer short memorable keywords of unique letters when teaching the method, and longer unique-letter keys when you want a denser scramble for recreational puzzles.
Never treat this cipher as a substitute for AES or authenticated encryption: frequency analysis breaks monoalphabetic maps on longer English text. Pair the tool with your lesson notes or puzzle brief so students can verify hand work against a stable reference.
What you can do with it
Classroom crypto demos
Show students how a keyword builds a mixed alphabet and how encrypt versus decrypt invert the same monoalphabetic map.
Puzzle and CTF warm-ups
Generate reversible ciphertext for scavenger hunts, escape rooms and introductory crypto challenges with a known keyword.
Light reversible obfuscation
Scramble short labels or notes with a shared keyword when you need quick round-trip mapping rather than real cryptography.
FAQ
What inputs does the keyword substitution cipher need?
Required text and keyword. Optional action is encrypt (default) or decrypt. The keyword must be unique A–Z letters only.
What happens if the keyword has a repeated letter?
Missing or empty keywords fail the same way. Invalid input is not charged.
Is the cipher deterministic and secure?
It is fully deterministic for the same text, keyword and action. It is a classical monoalphabetic cipher for teaching and puzzles, not modern cryptographic security.
How is the cipher alphabet built from the keyword?
The keyword's letters are written first, each only once, and the unused letters of A to Z follow in their usual order. CRYPTO gives CRYPTOABDEFGHIJKLMNQSUVWXZ, so plain A becomes C, B becomes R and C becomes Y.
Are spaces, digits and punctuation changed?
No. Only letters go through the substitution; spaces, digits and punctuation are copied as they are, so dates and codes stay readable. Each letter also keeps its case, which is why Hello turns into Btggj.
Related tools
For developers — API access
Everything on this page is available programmatically. This section is for teams who want to wire it into their own systems; everyone else can just use the tool above.
API endpoint
Prefer to automate it? One authenticated POST creates the task; the result comes back by webhook or a signed link. The same capability also runs here on the web, by email and from Telegram — and soon from our app too.
Call it from your stack
curl -X POST https://api.kit.forhosting.com/enc/keyword-cipher \
-H "Authorization: Bearer $KIT_KEY" \
-H "Content-Type: application/json" \
-d '{"text":"Hello World","keyword":"CRYPTO"}'const res = await fetch("https://api.kit.forhosting.com/enc/keyword-cipher", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.KIT_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
"text": "Hello World",
"keyword": "CRYPTO"
})
});
const { task_id } = await res.json();import os, requests
res = requests.post(
"https://api.kit.forhosting.com/enc/keyword-cipher",
headers={"Authorization": f"Bearer {os.environ['KIT_KEY']}"},
json={
"text": "Hello World",
"keyword": "CRYPTO"
},
)
task_id = res.json()["task_id"]<?php
$res = file_get_contents("https://api.kit.forhosting.com/enc/keyword-cipher", false, stream_context_create([
"http" => [
"method" => "POST",
"header" => "Authorization: Bearer " . getenv("KIT_KEY") . "\r\nContent-Type: application/json",
"content" => '{"text":"Hello World","keyword":"CRYPTO"}',
],
]));
$task = json_decode($res, true);body := bytes.NewBufferString(`{"text":"Hello World","keyword":"CRYPTO"}`)
req, _ := http.NewRequest("POST", "https://api.kit.forhosting.com/enc/keyword-cipher", body)
req.Header.Set("Authorization", "Bearer "+os.Getenv("KIT_KEY"))
req.Header.Set("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)Example request
{
"text": "Hello World",
"keyword": "CRYPTO"
}Example response
{
"task_id": "tsk_a1b2c3d4e5f6a1b2c3d4e5f6",
"type": "enc.keyword_cipher",
"status": "queued",
"_links": {
"result": "/tasks/tsk_…/result"
}
}The API is asynchronous: the call returns a task_id immediately and the result arrives by webhook. Polling is capped at 1 req/s per task.
Pricing
Published price — no tokens, no invented credits. A failed task is never charged.
Errors
| HTTP | Code | Meaning |
|---|---|---|
401 | unauthorized | Missing or invalid API key. |
402 | insufficient_balance | Your balance doesn't cover the task price. |
404 | unknown_type | That task type doesn't exist. |
429 | rate_limited | Too many requests. Use the webhook instead of polling. |
Technical notes
Missing keywords and keys with repeated letters fail immediately with invalid_input so bad material never looks like a successful cipher. Run free in the browser or call the identical deterministic logic through the API at $0.002 per successful request.
Encrypt, decrypt and validate the keyword
If the keyword is missing or empty after trim, the call fails with invalid_input naming the missing keyword. If any letter appears more than once, the call fails naming the repeated letter so you can fix the key instead of receiving a silently altered alphabet. On success the response echoes the original text, the normalized uppercase keyword, the action used, the full twenty-six letter mixed alphabet, the transformed result string, and a count of how many alphabetic characters were mapped.
Using the API, pricing and practical tips
Pricing for the hosted API is a flat $0.002 per successful request; validation failures such as a missing keyword or a repeated letter do not consume balance. For pipelines, submit each message as its own task and collect results through your usual webhook or signed-link flow. Keep field names explicit rather than packing free-form prose: the contract stays aligned with OpenAPI, SDK types and form controls, and it avoids ambiguous parsing of key versus message.
Technical questions
What does a successful response include?
The original text, normalized keyword, action, full mixed alphabet, the result string, and letters_mapped (count of A–Z characters substituted).
How much does the keyword cipher API cost?
Each successful API call costs $0.002. The same engine runs free in your browser with no account required.