{ "nbformat": 4, "nbformat_minor": 0, "metadata": { "colab": { "name": "Code Kids - Cyber Security - Password Projects.ipynb", "provenance": [], "collapsed_sections": [] }, "kernelspec": { "name": "python3", "display_name": "Python 3" }, "language_info": { "name": "python" } }, "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# ๐Ÿ” Code Kids Cyber Security Camp\n", "## Day 2 โ€” Python Password Projects\n", "\n", "Welcome, **Cyber Security Explorers**! ๐Ÿ•ต๏ธ\n", "\n", "Today you're going to build four Python projects that teach you how passwords actually work. By the end, you'll understand:\n", "\n", "1. How websites check if your password is correct\n", "2. How to hide your password while you type it (so nobody peeks)\n", "3. How websites store passwords safely using **hashing**\n", "4. How to check if a password is strong or weak\n", "\n", "Work through each project in order. Each one builds on what you learned before. Read the explanation, then run the code by clicking the โ–ถ๏ธ play button next to it.\n", "\n", "---\n", "\n", "**Remember the Cyber Security Explorer code:**\n", "- ๐Ÿ›ก๏ธ Use these skills to PROTECT yourself and others\n", "- ๐Ÿšซ Never use these skills to harm anyone or hack accounts that aren't yours\n", "- ๐Ÿ’ก If you discover a real security problem, tell a trusted adult\n", "\n", "Let's get hacking! ๐Ÿš€\n", "\n", "---\n", "*Code Kids Robotics Limited ยท codekids.org.uk*" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# ๐Ÿ”‘ Project 1: Simple Password Login\n", "\n", "### What you'll learn\n", "- How websites store usernames and passwords\n", "- How a login check actually works\n", "- Why this simple version is **dangerous** for real websites\n", "\n", "### How it works\n", "Every time you log into a website (Roblox, your school account, anything), the website checks:\n", "\n", "1. Does this username exist?\n", "2. Does the password match what we have stored?\n", "\n", "If both are YES, you're in. If either is NO, you stay out.\n", "\n", "Run the code below. Try logging in with the test accounts. Then try a wrong password and see what happens!\n", "\n", "โš ๏ธ **Important:** This is a *simple* example for learning. Real websites NEVER store passwords like this. You'll see why in Project 3." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Project 1: Simple Password Login\n", "# Learn how passwords protect accounts.\n", "# Fill in each TODO. Read the hints carefully!\n", "\n", "print(\"=\" * 50)\n", "print(\" CODE KIDS SECURE LOGIN\")\n", "print(\"=\" * 50)\n", "\n", "# TODO 1: Create a dictionary called `users` with 3 test accounts.\n", "# Each entry should have a username as the key and a password as the value.\n", "# Example: users = {\"alex\": \"sunshine123\", \"jordan\": \"mountain456\", ...}\n", "users = {\n", " # YOUR ACCOUNTS HERE\n", "}\n", "\n", "# TODO 2: Show the user the test accounts they can try.\n", "print(\"\\nTry logging in with these test accounts:\")\n", "# YOUR CODE HERE โ€” print at least one username/password pair\n", "\n", "# TODO 3: Use input() to ask the user for their username and password.\n", "username = input(\"\\nEnter your username: \")\n", "password = input(\"Enter your password: \")\n", "\n", "# TODO 4: Check if the login is correct.\n", "# Hint: use `if username in users and users[username] == password:`\n", "# If correct, print a success message.\n", "# If wrong, print a failure message.\n", "\n", "# YOUR CODE HERE\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### ๐Ÿค” Think about it\n", "\n", "1. **Try logging in with `alex` and password `wrong`** โ€” what happens?\n", "2. **Look at the code carefully.** Anyone reading this code can see ALL the passwords. Is that safe?\n", "3. **In real websites, where do you think they actually store passwords?**\n", "\n", "Keep these questions in mind โ€” we'll fix the problems in Project 3!" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# ๐Ÿ‘๏ธ Project 2: Password Masking with Asterisks\n", "\n", "### What you'll learn\n", "- Why your password should be HIDDEN while you type it\n", "- How to use the `maskpass` library to show asterisks (*) instead of letters\n", "- The difference between **security** and **privacy** when typing passwords\n", "\n", "### Why does this matter?\n", "\n", "Imagine you're logging into your Roblox account at school. Your friend is right behind you, watching the screen. If your password shows up as text, they can see every letter!\n", "\n", "That's why real password fields show `********` instead of your actual password.\n", "\n", "### First โ€” let's install the library\n", "Run the cell below. It installs a Python library called `maskpass` that hides your password while you type." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Install the maskpass library\n", "# The exclamation mark tells Colab to run this as a system command\n", "!pip install maskpass --quiet\n", "print(\"โœ… maskpass installed!\")\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Now let's use it!\n", "\n", "In the code below, notice the difference: the **username** is typed normally with `input()`, but the **password** uses `maskpass.askpass()` which hides what you type.\n", "\n", "Try it โ€” type your password and watch how it shows asterisks instead of letters! ๐Ÿ”’" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Project 2: Password Masking with Asterisks\n", "# Learn how to hide passwords while typing.\n", "\n", "# TODO 1: Import the maskpass library at the top.\n", "# Hint: `import maskpass`\n", "# YOUR IMPORT HERE\n", "\n", "print(\"=\" * 50)\n", "print(\" CODE KIDS SECURE LOGIN (Version 2)\")\n", "print(\"=\" * 50)\n", "\n", "# TODO 2: Copy your `users` dictionary from Project 1.\n", "users = {\n", " # YOUR ACCOUNTS HERE\n", "}\n", "\n", "print(\"\\nNotice how your password gets HIDDEN with asterisks!\")\n", "print(\"\\n(Use one of the test accounts you set up.)\")\n", "\n", "# TODO 3: Get the username normally with input().\n", "username = input(\"\\nEnter your username: \")\n", "\n", "# TODO 4: Get the password using maskpass.askpass() so it shows asterisks.\n", "# Hint: `maskpass.askpass(prompt=\"Enter your password: \", mask=\"*\")`\n", "password = None # โ† replace None with a call to maskpass.askpass\n", "\n", "# TODO 5: Check the login like in Project 1.\n", "# Print success if correct, failure if not.\n", "# Bonus: if success, mention that the password was hidden while typing.\n", "\n", "# YOUR CODE HERE\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### ๐Ÿค” Think about it\n", "\n", "1. **Why is masking important even in your bedroom at home?** (Hint: screen recording, screen sharing, video calls)\n", "2. **What other situations might someone \"shoulder surf\" your password?**\n", "3. **Is the password actually MORE secure with masking?** (Tricky question โ€” think about it!)\n", "\n", "**Answer to question 3:** No! The password itself is exactly the same. Masking is about **privacy from people watching**, not about making the password harder to crack. That's a different problem โ€” and that's what Project 3 fixes!" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# ๐Ÿ” Project 3: Cryptographic Hashing\n", "\n", "### What you'll learn\n", "- Why real websites NEVER store your actual password\n", "- What \"hashing\" means and how it protects you\n", "- How even a tiny change makes a completely different hash\n", "\n", "### The BIG problem with our login from Project 1\n", "\n", "Look back at Project 1. We stored passwords like this:\n", "\n", "```python\n", "users = {\n", " \"alex\": \"sunshine123\",\n", " \"jordan\": \"mountain456\"\n", "}\n", "```\n", "\n", "**Imagine if hackers broke into the website's database.** They'd see EVERY password! ๐Ÿ˜ฑ\n", "\n", "Real websites solve this with **hashing**. When you create an account:\n", "\n", "1. You type your password: `sunshine123`\n", "2. The website runs it through a **hash function** (a special one-way scrambler)\n", "3. The website stores the SCRAMBLED version: `0d1ee2c5ef...` (a long string of random-looking characters)\n", "4. Your actual password is **thrown away forever**\n", "\n", "When you log in next time:\n", "1. You type your password again\n", "2. The website hashes it again and compares the two hashes\n", "3. If they match โ€” you're in! If not โ€” login failed!\n", "\n", "### The magic part\n", "**Hashing is one-way.** You CAN'T reverse a hash to get the original password. Even if hackers steal the whole database, they only get the scrambled hashes โ€” not your real passwords.\n", "\n", "Let's see it in action!" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Project 3: Cryptographic Hashing\n", "# Learn how websites protect your password using a one-way scrambler.\n", "\n", "# TODO 1: Import the hashlib library.\n", "# Hint: `import hashlib`\n", "# YOUR IMPORT HERE\n", "\n", "print(\"=\" * 50)\n", "print(\" CODE KIDS PASSWORD HASHING\")\n", "print(\"=\" * 50)\n", "\n", "# TODO 2: Write a function `hash_password(password)` that:\n", "# - takes a password (a string)\n", "# - encodes it to bytes with .encode()\n", "# - hashes those bytes with hashlib.sha256(...)\n", "# - returns the result as a hex string with .hexdigest()\n", "#\n", "# Hint (one line): return hashlib.sha256(password.encode()).hexdigest()\n", "\n", "def hash_password(password):\n", " pass # โ† replace this with your one-line solution\n", "\n", "\n", "# TODO 3: Try your function on the password \"sunshine123\".\n", "# Print the original password and the hash side by side.\n", "example_password = \"sunshine123\"\n", "example_hash = None # โ† call your hash_password function\n", "\n", "print(f\"\\nOriginal password: {example_password}\")\n", "print(f\"Hashed password: {example_hash}\")\n", "print(\"\\n๐Ÿ”’ You can't reverse the hash to get the original password!\")\n", "print(\" Even the website doesn't know what your password actually is.\")\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Try it yourself!\n", "\n", "Now run the cell below and type your OWN password. Watch what happens when you hash it. Then try the same password again โ€” notice that the same password always gives the SAME hash. That's how login checking works!" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Try hashing your OWN password (using asterisks so nobody sees it).\n", "\n", "# TODO 1: Import maskpass and hashlib.\n", "# YOUR IMPORTS HERE\n", "\n", "print(\"=\" * 50)\n", "print(\" TRY IT YOURSELF\")\n", "print(\"=\" * 50)\n", "\n", "# TODO 2: Write your hash_password function again (or copy it from the cell above).\n", "def hash_password(password):\n", " pass\n", "\n", "# TODO 3: Use maskpass.askpass() to get a password from the user.\n", "print(\"\\nType any password (use the asterisk masking!):\")\n", "my_password = None # โ† maskpass.askpass(prompt=\"Password: \", mask=\"*\")\n", "\n", "# TODO 4: Hash the password using your function.\n", "my_hash = None # โ† call hash_password\n", "\n", "# TODO 5: Print the hash, the length of the password, and the length of the hash.\n", "# What do you notice about the hash length? It's ALWAYS the same!\n", "print(f\"\\nYour password was hashed to:\")\n", "print(f\" {my_hash}\")\n", "# YOUR CODE HERE for the lengths\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Watch the magic โ€” tiny changes, huge differences\n", "\n", "Here's the really cool part. Even if you change ONE letter of your password, the hash becomes completely different. This is called the **avalanche effect**.\n", "\n", "Run the cell below to see it:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Project 3 โ€” The Avalanche Effect\n", "# Tiny change in password = COMPLETELY different hash.\n", "\n", "import hashlib\n", "\n", "def hash_password(password):\n", " return hashlib.sha256(password.encode()).hexdigest()\n", "\n", "print(\"=\" * 50)\n", "print(\" THE AVALANCHE EFFECT\")\n", "print(\"=\" * 50)\n", "\n", "# TODO: Create THREE test passwords that are ALMOST identical.\n", "# Change just one tiny thing each time. Examples:\n", "# - Change the last digit\n", "# - Capitalise the first letter\n", "# - Swap one letter for a similar one (e for 3, etc.)\n", "test_1 = \"sunshine123\"\n", "test_2 = \"\" # โ† Change one tiny thing\n", "test_3 = \"\" # โ† Change one different tiny thing\n", "\n", "# TODO: Print each password and its hash. Look carefully โ€” even though the\n", "# passwords are nearly identical, the hashes are wildly different.\n", "print(f\"\\nPassword 1: '{test_1}'\")\n", "print(f\"Hash 1: {hash_password(test_1)}\")\n", "# YOUR CODE HERE for password 2 and password 3\n", "\n", "print(\"\\n๐Ÿคฏ Look how completely different the hashes are!\")\n", "print(\"Even tiny changes to a password create totally different hashes.\")\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### ๐Ÿค” Think about it\n", "\n", "1. **Why is it good that even one letter changes the entire hash?**\n", "2. **If two people happen to have the same password, would their hashes look the same?** (Yes! That's actually a problem โ€” real websites add something called \"salt\" to fix it, but that's a topic for another day.)\n", "3. **Does this mean your password is unhackable?** \n", "\n", "**Answer to question 3:** No! Hashing protects you from database breaches, but attackers can still:\n", "- Guess your password (Project 4 will help with this!)\n", "- Trick you into giving it away (phishing โ€” see the phishing games)\n", "- Use brute force on weak passwords (see the brute force demo)\n", "\n", "That's why ALL the cyber security skills you learn this week work together! ๐Ÿ›ก๏ธ" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# ๐Ÿ’ช Project 4: Password Strength Checker\n", "\n", "### What you'll learn\n", "- What makes a password strong or weak\n", "- How to build a tool that gives instant feedback\n", "- The five rules of a really strong password\n", "\n", "### What we're building\n", "A real tool you can use to check if your passwords are strong enough. It checks:\n", "\n", "| Check | Why it matters |\n", "|-------|----------------|\n", "| **Length** (at least 8 characters) | Longer = exponentially harder to crack |\n", "| **Lowercase letters** (a-z) | Adds variety |\n", "| **Uppercase letters** (A-Z) | Adds even more variety |\n", "| **Numbers** (0-9) | Even more combinations |\n", "| **Special characters** (!@#$%) | Makes brute force much harder |\n", "\n", "### The maths bit (for the curious)\n", "\n", "Each character type you add MULTIPLIES the number of possible passwords:\n", "- Only lowercase: 26 possibilities per character\n", "- Lowercase + numbers: 36 possibilities per character\n", "- Lowercase + uppercase + numbers + symbols: ~95 possibilities per character\n", "\n", "For an 8-character password:\n", "- Lowercase only: 208 BILLION combinations\n", "- All four types: 6,634 TRILLION combinations ๐Ÿคฏ\n", "\n", "Let's build the checker!" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Project 4: Password Strength Checker\n", "# Build your own tool that rates passwords as weak, medium, or strong.\n", "\n", "import maskpass\n", "\n", "print(\"=\" * 50)\n", "print(\" CODE KIDS PASSWORD STRENGTH CHECKER\")\n", "print(\"=\" * 50)\n", "\n", "def check_password_strength(password):\n", " \"\"\"Check a password and return strength, score, and feedback.\"\"\"\n", " score = 0\n", " feedback = []\n", "\n", " # ---- Check 1: LENGTH (this one is done for you as an example) ----\n", " if len(password) >= 12:\n", " score += 2\n", " feedback.append(\"โœ… Great length (12+ characters)\")\n", " elif len(password) >= 8:\n", " score += 1\n", " feedback.append(\"โš ๏ธ Okay length (8-11 characters) โ€” longer is better!\")\n", " else:\n", " feedback.append(\"โŒ Too short (less than 8 characters)\")\n", "\n", " # ---- Check 2: LOWERCASE letters ----\n", " # TODO: Loop through every character in `password`.\n", " # If any character is lowercase (use char.islower()), set has_lowercase = True.\n", " # If True at the end, score += 1 and add a โœ… message to feedback.\n", " # If not, add a โŒ message.\n", " # YOUR CODE HERE\n", "\n", " # ---- Check 3: UPPERCASE letters ----\n", " # TODO: Same idea as Check 2, but use char.isupper().\n", " # YOUR CODE HERE\n", "\n", " # ---- Check 4: NUMBERS (0-9) ----\n", " # TODO: Same idea, use char.isdigit().\n", " # YOUR CODE HERE\n", "\n", " # ---- Check 5: SPECIAL characters ----\n", " # special_chars = \"!@#$%^&*()_+-=[]{}|;:,.<>?/~`\"\n", " # TODO: Check if any char in `password` is in `special_chars`.\n", " # YOUR CODE HERE\n", "\n", " # ---- Determine overall strength based on total score ----\n", " if score >= 5:\n", " strength = \"๐Ÿ’ช STRONG\"\n", " elif score >= 3:\n", " strength = \"๐Ÿ‘Œ MEDIUM\"\n", " else:\n", " strength = \"โš ๏ธ WEAK\"\n", "\n", " return strength, score, feedback\n", "\n", "\n", "# ---- Try it out ----\n", "print(\"\\nLet's check how strong your password is!\")\n", "print(\"(Don't use your REAL password โ€” make one up to test)\")\n", "\n", "password = maskpass.askpass(prompt=\"\\nEnter a password to check: \", mask=\"*\")\n", "\n", "strength, score, feedback = check_password_strength(password)\n", "\n", "print(\"\\n\" + \"=\" * 50)\n", "print(\" RESULTS\")\n", "print(\"=\" * 50)\n", "print(f\"\\nOverall strength: {strength}\")\n", "print(f\"Score: {score} out of 6\")\n", "print(\"\\nBreakdown:\")\n", "for item in feedback:\n", " print(f\" {item}\")\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Try it with different passwords!\n", "\n", "Run the cell above multiple times with different passwords to see how it scores them. Try:\n", "\n", "| Password to try | Expected result |\n", "|-----------------|-----------------|\n", "| `password` | Very weak |\n", "| `password123` | Still weak |\n", "| `Password123` | Medium |\n", "| `MyDog$Name42` | Strong |\n", "| `correcthorsebatterystaple` | Strong (it's super long!) |\n", "\n", "### Bonus challenge ๐Ÿ†\n", "\n", "Can you modify the code above to also check if the password contains common weak patterns? For example:\n", "- Does it contain the word \"password\"?\n", "- Is it just a single dictionary word?\n", "- Does it contain a sequence like \"123\" or \"abc\"?\n", "\n", "Try adding extra checks to make the tool even smarter!" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# ๐ŸŽ‰ You did it!\n", "\n", "### What you've learned today\n", "\n", "| Project | Skill |\n", "|---------|-------|\n", "| 1: Simple Login | How password checking works |\n", "| 2: Password Masking | Why passwords should be hidden while typing |\n", "| 3: Hashing | How real websites protect your passwords |\n", "| 4: Strength Checker | How to make passwords that are hard to crack |\n", "\n", "### The five rules of a really strong password\n", "\n", "1. ๐Ÿ“ **Length first** โ€” go for at least 12 characters\n", "2. ๐ŸŽจ **Mix it up** โ€” uppercase, lowercase, numbers, AND symbols\n", "3. ๐Ÿคซ **Don't use personal info** โ€” no pet names, birthdays, favourite teams (attackers find these on social media!)\n", "4. ๐Ÿ” **Don't reuse passwords** โ€” different password for every account\n", "5. ๐Ÿค– **Consider a password manager** โ€” let it generate and remember complex passwords for you\n", "\n", "### What's next?\n", "\n", "Now that you understand passwords, you're ready for the Phishing Defender game and Social Engineering Challenge. Time to put your skills to the test! ๐Ÿ›ก๏ธ\n", "\n", "---\n", "\n", "*Code Kids Robotics Limited ยท codekids.org.uk*\n", "*Cyber Security Holiday Camp ยท Day 2*" ] } ] }