Worked example: If users complete 48 successful interactions in 30 minutes, efficiency is \(48/30=1.6\) successful interactions/minute. This metric helps compare alternative game or wizard designs objectively.
25.1 Learning Objectives
By completing this interactive game, you will be able to:
Apply classical ciphers: Encode and decode messages using Caesar and substitution ciphers
Distinguish modern encryption modes: Compare block cipher modes, key sizes, and authenticated encryption
Apply asymmetric concepts: Implement public/private key principles and digital signatures
Identify vulnerabilities: Detect weak encryption patterns and common attack vectors
In 60 Seconds
Interactive games and simulations help learners develop intuition for cryptographic concepts by experiencing encryption, key exchange, and attack scenarios hands-on rather than through abstract theory alone.
For Beginners: Cipher Challenge Game
Cryptography for IoT is the science of keeping sensor data and device commands secret and tamper-proof. Think of it as the digital equivalent of secret codes, locked boxes, and wax seals. Even if someone intercepts your IoT data traveling through the air, cryptography ensures they cannot read or alter it without the proper keys.
Sensor Squad: Game Time – Crack the Code!
“Who wants to play a cipher game?” Lila the LED blinked excitedly. “This interactive challenge lets you try out real encryption techniques, starting with the classic Caesar cipher that Julius Caesar used 2,000 years ago!”
Sammy the Sensor tried the first puzzle. “The Caesar cipher shifts each letter by a fixed number. If the shift is 3, then A becomes D, B becomes E, and so on. It is super easy to break – there are only 26 possible shifts! That is why we do not use it for real security, but it is a great way to understand the basics.”
“As you level up, the challenges get harder,” Max the Microcontroller said. “You will work with substitution ciphers, then AES block cipher modes, then asymmetric encryption puzzles. Each level teaches a real concept that professional cryptographers use every day. The goal is to build intuition about why some ciphers are strong and others are weak.”
“My tip: try to break the weak ciphers first!” Bella the Battery suggested. “When you see HOW easy it is to crack a Caesar cipher or a simple substitution, you will understand WHY modern encryption uses 256-bit keys and complex mathematical operations. Play the game, have fun, and you will learn cryptography without even realizing it!”
How to Play
Test your cryptography knowledge through progressively challenging puzzles:
Select a level to begin
Solve each challenge by applying the correct cryptographic technique
Earn points for correct answers (faster = more points)
mutable gameState = ({currentLevel:1,currentChallenge:0,score:0,totalCorrect:0,totalAttempts:0,showHint:false,showAnswer:false,userAnswer:""})// Level 1: Classical Cipherslevel1Challenges = [ {title:"Caesar Cipher Encoding",instruction:"Encrypt 'HELLO' using a Caesar cipher with shift of 3",answer:"KHOOR",hint:"H shifts to K, E shifts to H, L shifts to O...",explanation:"Caesar cipher shifts each letter by the key value. H->K (+3), E->H (+3), L->O (+3), L->O (+3), O->R (+3).",points:100 }, {title:"Caesar Cipher Decoding",instruction:"Decrypt 'VHFXUH' using a Caesar cipher with shift of 3",answer:"SECURE",hint:"V shifts back to S, H shifts back to E...",explanation:"To decrypt, shift each letter backward. V->S (-3), H->E (-3), F->C (-3), X->U (-3), U->R (-3), H->E (-3).",points:100 }, {title:"Crack the Cipher",instruction:"The message 'LRW' was encrypted with an unknown shift. What IoT word is it?",answer:"IOT",hint:"Try common IoT words. The shift is between 1-5.",explanation:"LRW decrypts to IOT with shift of 3. L->I (-3), R->O (-3), W->T (-3).",points:150 }, {title:"XOR Basics",instruction:"If 'A' (ASCII 65) is XORed with key 42, what decimal value results?",answer:"107",hint:"65 XOR 42 = ? (01000001 XOR 00101010)",explanation:"65 XOR 42 = 107. XOR is reversible: 107 XOR 42 = 65. XOR is a core operation used in AES (the AddRoundKey step).",points:150 }, {title:"Pattern Analysis",instruction:"In ciphertext 'WKLV LV VHFUHW', what does repeated 'LV' likely represent?",answer:"IS",hint:"LV appears twice. What 2-letter word commonly repeats?",explanation:"Pattern: 'IS' is common. Full decode: 'THIS IS SECRET'. This is why substitution ciphers are weak.",points:100 }]// Level 2: Symmetric Encryptionlevel2Challenges = [ {title:"ECB Mode Vulnerability",instruction:"An ECB-encrypted image shows penguin outlines. Which option explains why?",options: ["Key too short","Identical blocks produce identical ciphertext","Image corrupted","Weak encryption"],answer:1,hint:"What happens when many pixels have the same color values?",explanation:"ECB encrypts each block independently. Identical plaintext blocks create identical ciphertext, revealing patterns.",points:200 }, {title:"CBC Mode Security",instruction:"In CBC mode, what must be random and unique for each message?",options: ["Encryption key","Block size","Initialization Vector (IV)","Padding scheme"],answer:2,hint:"The first block has no previous ciphertext to XOR with...",explanation:"The IV provides randomness for the first block. Same plaintext + same key + different IV = different ciphertext.",points:200 }, {title:"AES Key Strength",instruction:"How many possible keys exist for AES-128?",options: ["128 keys","256 keys","2^128 keys (about 3.4 x 10^38)","2^256 keys"],answer:2,hint:"The '128' in AES-128 refers to the key length in bits...",explanation:"2^128 possible keys = 340,282,366,920,938,463,463,374,607,431,768,211,456. Would take trillions of years to brute-force.",points:150 }, {title:"Authenticated Encryption",instruction:"What does AES-GCM provide that AES-CBC doesn't?",options: ["Faster speed","Smaller ciphertext","Built-in integrity verification","Quantum resistance"],answer:2,hint:"GCM produces an authentication tag that verifies...",explanation:"AES-GCM detects ANY tampering via its authentication tag. CBC only provides confidentiality.",points:200 }, {title:"Key Derivation",instruction:"Why use PBKDF2 instead of directly using a password as an AES key?",options: ["Passwords are always 128 bits","KDFs slow down brute-force attacks","AES needs numeric keys","Passwords have illegal chars"],answer:1,hint:"Attackers can guess millions of passwords per second...",explanation:"KDFs apply thousands of iterations, making each password guess expensive. Buys time against brute-force.",points:200 }]// Level 3: Asymmetric Encryptionlevel3Challenges = [ {title:"Public Key Usage",instruction:"Which key should an IoT sensor use to encrypt data for a cloud server?",options: ["Sensor's private key","Sensor's public key","Server's public key","Server's private key"],answer:2,hint:"Anyone can encrypt with a public key, but only private key holder can decrypt...",explanation:"Encrypt with SERVER'S PUBLIC key. Only the server (with private key) can decrypt.",points:250 }, {title:"Digital Signatures",instruction:"To sign a firmware update, the manufacturer should use:",options: ["Device's public key","Manufacturer's public key","Manufacturer's private key","Shared symmetric key"],answer:2,hint:"Only one entity should be able to create valid signatures...",explanation:"Sign with PRIVATE key, verify with PUBLIC key. Only manufacturer can sign; everyone can verify.",points:250 }, {title:"Signature Verification",instruction:"After computing firmware hash and decrypting signature, what should the device compare?",options: ["Original firmware and signature","Computed hash and decrypted signature hash","Public and private keys","Firmware size"],answer:1,hint:"Signatures are created by encrypting a HASH...",explanation:"Compare computed hash with decrypted hash from signature. If they match, firmware is authentic.",points:300 }, {title:"Diffie-Hellman Security",instruction:"An eavesdropper sees the public values A and B. Can they compute the shared secret?",options: ["Yes, by multiplying values","Yes, by solving equation","No, discrete log is hard","No, values are encrypted"],answer:2,hint:"Computing 'a' from g^a mod p is the discrete logarithm problem...",explanation:"Discrete logarithm is computationally infeasible for large primes. Eavesdropper cannot compute shared secret.",points:300 }, {title:"Hybrid Encryption",instruction:"Why does TLS use asymmetric crypto (e.g., ECDHE) for key exchange, then switch to AES for data?",options: ["Asymmetric crypto is more secure","AES cannot encrypt large data","Asymmetric is slow for bulk data; AES needs secure key exchange","AES keys expire"],answer:2,hint:"Asymmetric operations are 100-1000x slower than AES...",explanation:"Asymmetric crypto solves key distribution. AES is fast for bulk data. TLS uses both: asymmetric (ECDHE) for handshake, symmetric (AES) for data.",points:300 }, {title:"Hash Properties",instruction:"If you change ONE bit of a 1GB file, what happens to the SHA-256 hash?",options: ["Only 1 bit changes","About half bits change (avalanche)","Hash stays same","Hash becomes invalid"],answer:1,hint:"Good hash functions have the 'avalanche effect'...",explanation:"Avalanche effect: tiny input change causes ~50% of bits to flip. Any modification is detectable.",points:250 }]allChallenges = ({1: level1Challenges,2: level2Challenges,3: level3Challenges})levelNames = ({1:"Classical Ciphers",2:"Symmetric Encryption",3:"Asymmetric Encryption"})
25.1.1 Game Interface
Show code
viewof selectedLevel = Inputs.radio([1,2,3], {value:1,label:"Select Level",format: x =>`Level ${x}: ${levelNames[x]}`})
This is a digit-based Caesar cipher with shift 3. Let’s demonstrate why this is completely insecure:
Step 1: Frequency Analysis
Attacker captures 100 encrypted readings: - “58.6” appears 15 times - “69.7” appears 12 times - “47.5” appears 10 times
Reasoning: Temperature sensors in a room typically cluster around comfortable range (20-25°C). The most frequent encrypted value likely corresponds to the most common actual temperature.
Step 2: Known Plaintext Attack
Attacker observes that weather station reports 22.3°C at the same time encrypted reading is “55.6”.
Plaintext: 22.3
Ciphertext: 55.6
Mapping:
2 → 5 (shift of 3)
3 → 6 (shift of 3)
Confirmed: This is Caesar cipher with shift 3
bfCalc = {const totalKeys =Math.pow(2, bfKeyBits);const seconds = totalKeys / bfAttackerSpeed;const minutes = seconds /60;const hours = minutes /60;const days = hours /24;const years = days /365.25;const universeAges = years /13.8e9;let timeStr, color, verdict;if (seconds <1) { timeStr = (seconds *1000).toFixed(3) +" milliseconds"; color ="#E74C3C"; verdict ="INSTANTLY BROKEN"; }elseif (seconds <60) { timeStr = seconds.toFixed(1) +" seconds"; color ="#E74C3C"; verdict ="TRIVIALLY BROKEN"; }elseif (minutes <60) { timeStr = minutes.toFixed(1) +" minutes"; color ="#E74C3C"; verdict ="EASILY BROKEN"; }elseif (hours <24) { timeStr = hours.toFixed(1) +" hours"; color ="#E67E22"; verdict ="BROKEN IN A DAY"; }elseif (days <365) { timeStr = days.toFixed(1) +" days"; color ="#E67E22"; verdict ="WEAK"; }elseif (years <1000) { timeStr = years.toFixed(1) +" years"; color ="#E67E22"; verdict ="MARGINAL"; }elseif (years <1e15) { timeStr = years.toExponential(2) +" years"; color ="#16A085"; verdict ="STRONG"; }else { timeStr = universeAges.toExponential(2) +" universe ages"; color ="#16A085"; verdict ="UNBREAKABLE"; }return {totalKeys, seconds, years, universeAges, timeStr, color, verdict};}html`<div style="background: linear-gradient(135deg, #2C3E50, #34495E); color: white; padding: 20px; border-radius: 10px; margin-top: 10px;"> <h4 style="margin-top: 0; color: #F1C40F;">Brute-Force Attack Estimate</h4> <div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); gap: 15px; margin-bottom: 15px;"> <div style="background: rgba(255,255,255,0.1); padding: 12px; border-radius: 8px; text-align: center;"> <div style="font-size: 0.8rem; opacity: 0.7;">Key Space</div> <div style="font-size: 1.1rem; font-weight: bold;">2^${bfKeyBits}</div> <div style="font-size: 0.75rem; opacity: 0.6;">${bfCalc.totalKeys.toExponential(2)} keys</div> </div> <div style="background: rgba(255,255,255,0.1); padding: 12px; border-radius: 8px; text-align: center;"> <div style="font-size: 0.8rem; opacity: 0.7;">Time to Crack</div> <div style="font-size: 1.1rem; font-weight: bold;">${bfCalc.timeStr}</div> </div> <div style="background: ${bfCalc.color}33; padding: 12px; border-radius: 8px; text-align: center; border: 2px solid ${bfCalc.color};"> <div style="font-size: 0.8rem; opacity: 0.7;">Verdict</div> <div style="font-size: 1.1rem; font-weight: bold; color: ${bfCalc.color};">${bfCalc.verdict}</div> </div> </div> <div style="font-size: 0.85rem; opacity: 0.8;"> <strong>Comparison:</strong> Caesar cipher (shift 0-25) = ~4.7 bits. AES-128 = 128 bits. Increasing key size by 1 bit doubles the brute-force time. Try setting the key size to 26 (number of Caesar shifts) to see why classical ciphers are trivial to break. </div></div>`
Decision Framework: When to Use Which Cipher Level
Based on the game levels, here’s how to match cipher complexity to real IoT needs:
Level 1: Classical Ciphers (Caesar, XOR)
Acceptable Use
NEVER Acceptable
Educational demonstrations
Production IoT security
Obfuscation of non-sensitive display data
Protecting sensor data
Checksums (weak integrity)
Authentication
Example acceptable use: Obfuscating debug messages in logs (not security, just readability).
Level 2: Symmetric Encryption (AES)
Use Case
Cipher Mode
Key Size
Bulk data encryption
AES-128-GCM
128-bit
High-security data
AES-256-GCM
256-bit
Streaming data
ChaCha20-Poly1305
256-bit
Legacy compatibility
AES-128-CBC + HMAC
128-bit + 256-bit
Decision criteria:
Do you have hardware AES acceleration?
├─ YES → Use AES-128-GCM or AES-256-GCM
│ └─ Performance: 100+ MB/s on ESP32
│
└─ NO → Use ChaCha20-Poly1305
└─ Performance: 2-3x faster than software AES
Level 3: Asymmetric Encryption (RSA/ECC)
Operation
Small Devices (<1 MB RAM)
Larger Devices
Key exchange
ECDH with Curve25519
ECDH with secp256r1 (if HW) or Curve25519
Digital signatures
Ed25519 (64-byte signatures)
Ed25519 or ECDSA secp256r1
Certificate-based auth
ECC-256 certificates
ECC-256 or RSA-2048
Decision tree:
What is your primary need?
│
├─ Encrypt data for long-term storage
│ └─ Use AES-256-GCM (Level 2)
│ (Symmetric is 100x faster than RSA)
│
├─ Establish shared key with unknown device
│ └─ Use ECDH key exchange (Level 3)
│ Then switch to AES for data
│
├─ Prove message authenticity
│ └─ Use Ed25519 signatures (Level 3)
│ Attach signature to data
│
└─ Verify data has not been modified
└─ Use SHA-256 hash (not a cipher)
Or AES-GCM auth tag if encrypted
energyCalc = {const costs = {"XOR (insecure)": {mj:0.001,secure:false},"AES-128-GCM": {mj:0.05,secure:true},"ChaCha20-Poly1305": {mj:0.08,secure:true},"ECDH Key Exchange": {mj:0.5,secure:true},"Ed25519 Signature": {mj:0.4,secure:true},"RSA-2048 Signature": {mj:20,secure:true} };const c = costs[energyCipher];const dailyMj = c.mj* energyMsgsPerDay;const dailyMah = dailyMj / (3.3*3.6);const batteryDays = energyBatteryMah / dailyMah;const batteryYears = batteryDays /365.25;const pctPerDay = (dailyMah / energyBatteryMah) *100;return {mj: c.mj,secure: c.secure, dailyMj,dailyMah: dailyMah.toFixed(4),batteryDays: batteryDays.toFixed(0),batteryYears: batteryYears.toFixed(2),pctPerDay: pctPerDay.toFixed(4)};}html`<div style="background: linear-gradient(135deg, #2C3E50, #34495E); color: white; padding: 20px; border-radius: 10px; margin-top: 10px;"> <h4 style="margin-top: 0; color: #F1C40F;">Energy Budget: ${energyCipher}</h4>${!energyCalc.secure?html`<div style="background: rgba(231,76,60,0.3); border: 2px solid #E74C3C; border-radius: 8px; padding: 10px; margin-bottom: 15px; font-weight: bold;"> WARNING: XOR is NOT secure encryption. The energy savings are meaningless because the data is completely exposed. </div>`:""} <div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); gap: 12px; margin-bottom: 15px;"> <div style="background: rgba(255,255,255,0.1); padding: 12px; border-radius: 8px; text-align: center;"> <div style="font-size: 0.8rem; opacity: 0.7;">Per Message</div> <div style="font-size: 1.2rem; font-weight: bold; color: #3498DB;">${energyCalc.mj} mJ</div> </div> <div style="background: rgba(255,255,255,0.1); padding: 12px; border-radius: 8px; text-align: center;"> <div style="font-size: 0.8rem; opacity: 0.7;">Daily Total</div> <div style="font-size: 1.2rem; font-weight: bold; color: #E67E22;">${energyCalc.dailyMj.toFixed(2)} mJ</div> </div> <div style="background: rgba(255,255,255,0.1); padding: 12px; border-radius: 8px; text-align: center;"> <div style="font-size: 0.8rem; opacity: 0.7;">Battery % / Day</div> <div style="font-size: 1.2rem; font-weight: bold; color: #16A085;">${energyCalc.pctPerDay}%</div> </div> <div style="background: rgba(255,255,255,0.1); padding: 12px; border-radius: 8px; text-align: center;"> <div style="font-size: 0.8rem; opacity: 0.7;">Battery Life</div> <div style="font-size: 1.2rem; font-weight: bold; color: #9B59B6;">${parseFloat(energyCalc.batteryYears) >100?">100 years": energyCalc.batteryYears+" years"}</div> </div> </div> <div style="font-size: 0.85rem; opacity: 0.8;"> <strong>Key insight:</strong> Even with ${energyMsgsPerDay.toLocaleString()} messages/day, AES-128-GCM uses only ${(0.05* energyMsgsPerDay).toFixed(1)} mJ daily — a negligible fraction of battery capacity. There is no valid energy argument for using weak encryption on IoT devices. </div></div>`
Common Mistake: Using XOR as “Good Enough” Encryption
The Mistake: Developers think XOR with a “random” key provides adequate security for low-value IoT data.
Code example (WRONG):
// IoT sensor "encryption"uint8_t secret_key[]={0x4A,0x7F,0x2E,0x9C};void encrypt_sensor_data(uint8_t*data,size_t len){for(size_t i =0; i < len; i++){ data[i]^= secret_key[i %4];// XOR with repeating key}}// "Encrypted" sensor reading sent over networkuint8_t reading[4]={25,0,0,0};// Temperature in °Cencrypt_sensor_data(reading,4);send_to_cloud(reading);
Why This Fails Catastrophically:
Attack 1: Known Plaintext
Attacker knows sensor readings are temperatures (likely 0-50°C):
# Captured ciphertextciphertext =bytes([0x53, 0x7F, 0x2E, 0x9C])# Guess: First byte is temperature 25°C (0x19)guessed_plaintext =25recovered_key_byte = ciphertext[0] ^ guessed_plaintext# recovered_key_byte = 0x53 ^ 0x19 = 0x4A ✓ (correct!)# Now decrypt everything:key = [0x4A, 0x7F, 0x2E, 0x9C]plaintext = [c ^ k for c, k inzip(ciphertext, key)]# Result: [25, 0, 0, 0] = 25°C
Attack 2: Crib Dragging (multiple messages with same key)
# Attacker captures two encrypted messages:ciphertext1 ="Temp:25°C"^ key # b'\x63\x04\x5a...'ciphertext2 ="Temp:26°C"^ key # b'\x63\x04\x5b...'# XOR the two ciphertexts:crib = ciphertext1 ^ ciphertext2# Result: "Temp:25°C" ^ "Temp:26°C"# = 0x00 0x00 0x00 0x00 0x01# Reveals: Plaintexts differ only in last byte!# Attacker now knows:# - Both messages start with "Temp:"# - Values are 25 and 26# - Can decrypt ALL future messages
Attack 3: Frequency Analysis
# Attacker collects 1000 encrypted readings# Counts most common first byte: 0x53 appears 150 times# Reasoning: Room temperature is typically 20-22°C# Most common encrypted value likely represents most common temperaturefor guess inrange(20, 25): possible_key =0x53^ guessprint(f"If plaintext was {guess}, key byte is {hex(possible_key)}")# Try each candidate key on all captured traffic# Correct key will produce sensible temperature values (0-50°C)# Wrong keys will produce garbage (>100°C or negative)
Real-World Consequences:
Case Study: Smart building HVAC system used XOR “encryption” for sensor data: - Attacker captured 1 hour of traffic (720 messages) - Used known plaintext attack (knew outdoor temperature from weather API) - Recovered encryption key in 5 minutes - Decrypted 6 months of archived sensor data - Sold occupancy patterns to competitor
Cost: $3M contract lost, $500K legal fees
Energy Savings from XOR: 0.001 mJ per message Security cost: Complete compromise
The Fix: Use AES-128-GCM
#include <mbedtls/gcm.h>// Proper authenticated encryption (simplified -- production code// must also call mbedtls_gcm_init and mbedtls_gcm_setkey)void encrypt_sensor_data_properly(constuint8_t*plaintext,size_t len,uint8_t*ciphertext,uint8_t*tag){ mbedtls_gcm_context ctx;uint8_t key[16]={/* Securely provisioned key */};uint8_t nonce[12];// Random nonce per message mbedtls_gcm_init(&ctx); mbedtls_gcm_setkey(&ctx, MBEDTLS_CIPHER_ID_AES, key,128);// Generate random nonce generate_random(nonce,12);// AES-128-GCM encryption mbedtls_gcm_crypt_and_tag(&ctx, MBEDTLS_GCM_ENCRYPT, len, nonce,12, NULL,0, plaintext, ciphertext,16, tag); mbedtls_gcm_free(&ctx);// Send: nonce || ciphertext || tag}
Energy cost: 0.05 mJ per message (50x more than XOR) Security benefit: Prevents ALL known attacks
The principle: Never implement your own encryption. The energy savings are negligible, but the security cost is total compromise. Always use standard, peer-reviewed algorithms.
Base64 and hex encoding are reversible transformations with no secret key — they provide zero security. Developers sometimes use encoding thinking it obscures data. Always distinguish between encoding (data format change) and encryption (requires a secret key).
2. Believing Security Through Obscurity Is Sufficient
Keeping the algorithm secret instead of the key is a fundamentally flawed approach. Modern cryptographic security relies on Kerckhoffs’s principle: the algorithm is public; only the key is secret.
3. Using Home-Grown Cryptography
Implementing custom ciphers or modifying standard algorithms almost always introduces subtle vulnerabilities invisible to non-experts. Use vetted libraries (OpenSSL, mbedTLS, libsodium) implementing standardized algorithms.
Label the Diagram
💻 Code Challenge
Order the Steps
Match the Concepts
25.5 Summary
This game covers:
Level 1: Classical ciphers show why simple substitution is insecure
Level 2: Block cipher modes, authentication, and key derivation
Level 3: Public-key cryptography, signatures, and key exchange
Understanding these concepts helps you make informed security decisions for IoT systems.
25.6 Knowledge Check
Quiz: Cipher Challenge Game
::
Key Concepts
Caesar Cipher: A simple substitution cipher shifting each letter by a fixed number of positions — historically significant, trivially broken by frequency analysis, but useful for illustrating basic encryption concepts.
Frequency Analysis: A cryptanalysis technique that exploits the non-uniform distribution of letters in natural language to break simple substitution ciphers.
Key Space: The set of all possible keys for a given cipher; a key space of 2^128 means an attacker must try up to 2^128 combinations in a brute-force attack.
Brute Force Attack: Systematically trying every possible key or password until the correct one is found; feasible only when key space is small.
Diffie-Hellman Key Exchange: A protocol allowing two parties to establish a shared secret over a public channel; the foundation of modern key exchange, illustrated well with color-mixing analogies.
Padding Oracle Attack: An attack exploiting error messages from a decryption system to deduce plaintext one byte at a time, demonstrating why authenticated encryption is essential.
Return to the Encryption Principles Overview for a complete guide to all encryption topics, or explore specific chapters for deeper coverage of any topic.