Skip to main content
Editor

Safe Computing: Privacy, Passwords, Encryption and Phishing

Beginner40 min3 exercises50 XP
0/3 exercises

Your phone, your browser and your apps collect a steady stream of data about you, and the same data that makes them convenient can be used to track you, trick you or steal from you.

Technology makes it easy for people, groups and institutions such as companies, schools and governments to collect information, use it, and sometimes exploit it. Knowing what is collected, and how attackers get in, is the first step to protecting yourself.

What is personally identifiable information?

Personally identifiable information (PII) is information about a person that identifies them, links to them, relates to them or describes them. Examples include:

  • Social Security number
  • age
  • race
  • phone numbers
  • medical information
  • financial information, such as bank account and credit card numbers
  • biometric data, such as fingerprints, face scans and voice prints
  • Some PII points to you alone, like a Social Security number. Other pieces, like your age or your ZIP code, look harmless on their own but can identify you once they are combined.

    Who collects data about you, and how?

    Data collection happens all the time, mostly in the background:

  • Search engines record and keep a history of what you search for. They use that history to suggest websites and to target ads at you.
  • Websites record a history of who has viewed their pages, often with cookies: small files a site stores in your browser so it can recognize you when you come back.
  • Devices, websites and networks can collect your location from GPS, nearby Wi-Fi networks and cell towers. Programs can record where you have been, how you got there and how long you stayed. A phone's location history can show every place you went last month, hour by hour.
  • Social media posts can be used by anyone who sees them, including people you never meant to reach.
  • How can separate pieces of data reveal who you are?

    Separate pieces of personal data, such as your location history, cookies and browsing history, can be combined to build a detailed picture of one person. A shopping site knows your ZIP code, a fitness app knows your running route, and a social network knows your school and your birthday. Each piece looks harmless. Together they can show where you live, when you are home and who you spend time with. Combining what you post on social media with other sources can reveal private facts you never posted.

    In 2000, computer scientist Latanya Sweeney showed that about 87% of Americans can be identified uniquely from three facts: their five-digit ZIP code, their gender and their full date of birth. Earlier, using public voter records, she had picked out the governor of Massachusetts's medical records from a dataset that was supposed to be anonymous. The demo does the same with invented data.

    Re-identifying an "anonymous" survey
    # INVENTED data. An "anonymous" health survey: no names, three facts.
    survey = [
    {"zip": "60614", "birthday": "2009-03-14", "gender": "F", "answer": "has asthma"},
    {"zip": "60614", "birthday": "2008-11-02", "gender": "M", "answer": "broke an arm"},
    {"zip": "60657", "birthday": "2009-03-14", "gender": "F", "answer": "takes allergy pills"},
    ]
    # A public sports-team roster that does include names
    roster = [
    {"name": "Ava Chen", "zip": "60614", "birthday": "2009-03-14", "gender": "F"},
    {"name": "Leo Park", "zip": "60614", "birthday": "2008-11-02", "gender": "M"},
    {"name": "Mia Ross", "zip": "60657", "birthday": "2010-07-21", "gender": "F"},
    ]
    for row in survey:
    facts = (row["zip"], row["birthday"], row["gender"])
    matches = [p["name"] for p in roster if (p["zip"], p["birthday"], p["gender"]) == facts]
    if len(matches) == 1:
    print(f"{matches[0]} {row['answer']}")
    else:
    print(f"No unique match for {facts}")
    Output
    Ava Chen has asthma
    Leo Park broke an arm
    No unique match for ('60657', '2009-03-14', 'F')

    What are the benefits and risks of sharing personal data?

    PII and other information you put online can make your experience better. A music app that knows what you play suggests songs you will like, and a map that knows your home address gives one-tap directions. Saved payment details and addresses turn an online purchase into a few taps.

    The risks are real, though:

  • Collected data can be exploited. When companies or governments gather and organize huge amounts of personal information, it can be misused if privacy and other protections are ignored. In 2018 the public learned that a personality-quiz app had collected data on up to 87 million Facebook users, most of whom never took the quiz, and that the firm Cambridge Analytica used it to target political ads. In 2015 hackers stole background-check records on 21.5 million people from the US Office of Personnel Management, including the fingerprints of 5.6 million.
  • Information gets used in ways you did not intend. An email can be forwarded, a post can be reshared, and colleges and employers look at applicants' social media. In 2017 Harvard withdrew admission offers from at least ten students over offensive memes they had posted in a private online group.
  • PII can be used to stalk someone, steal their identity, or plan other crimes. A photo captioned "beach all week!" tells a burglar that the house is empty. A name, birthday and Social Security number can be enough to open a credit card in someone else's name.
  • Once information is online, it is hard to delete. Screenshots, copies and archives can survive long after you remove the original.
  • Check your understanding

    Which two are examples of personally identifiable information? Select two answers.

    Select 2 answers.

    Answers

    Kai never posts his address. His public posts do include a photo of his house with the street sign visible, a check-in at the same gym every weekday at 6 a.m., and his school team's jersey. Which risk does this show best?

    Answers

    How do passwords and multifactor authentication protect you?

    Authentication checks that you are who you claim to be before it lets you into a device or account. Two common measures are strong passwords and multifactor authentication.

    A strong password is easy for you to remember but hard for anyone else to guess, even someone who knows you. Your dog's name plus your birth year fails that test, because a classmate could guess it. A passphrase of several unrelated words, like violet-tractor-pancake-river-sofa-maple, is easy to picture and very hard to guess.

    Password-guessing programs try billions of passwords a second. How long a password holds out depends on how many possibilities there are: the number of characters it could use, raised to the power of its length. The demo counts them, assuming an attacker who can try 10 billion passwords a second.

    How many possible passwords?
    GUESSES_PER_SECOND = 10_000_000_000 # an assumption: a fast cracking computer
    def readable_time(seconds):
    years = seconds / (365 * 24 * 3600)
    if years >= 1_000_000_000:
    return f"{years:.1e} years"
    for unit, size in [("years", 365 * 24 * 3600), ("days", 86400), ("hours", 3600), ("minutes", 60)]:
    if seconds >= size:
    return f"{seconds / size:,.0f} {unit}"
    return f"{seconds:.2f} seconds"
    examples = [
    ("6 lowercase letters", 26, 6),
    ("8 letters and digits", 62, 8),
    ("12 keyboard characters", 95, 12),
    ("6 random common words", 7776, 6), # from a list of 7,776 words
    ]
    for label, characters, length in examples:
    possibilities = characters ** length
    time_needed = readable_time(possibilities / GUESSES_PER_SECOND)
    print(f"{label:<24} {possibilities:.1e} possibilities, {time_needed} to try them all")
    Output
    6 lowercase letters      3.1e+08 possibilities, 0.03 seconds to try them all
    8 letters and digits     2.2e+14 possibilities, 6 hours to try them all
    12 keyboard characters   5.4e+23 possibilities, 1,713,471 years to try them all
    6 random common words    2.2e+23 possibilities, 701,021 years to try them all

    These counts assume every character or word is chosen at random. Real attackers try common passwords, dictionary words and personal details first, so Fluffy2009 falls quickly even though it is 10 characters long.

    Multifactor authentication (MFA) grants access only after you present several separate pieces of evidence, typically from at least two of these categories:

  • Knowledge: something you know, like a password or a PIN.
  • Possession: something you have, like your phone receiving a code, or a security key.
  • Inherence: something you are, like a fingerprint or your face.
  • MFA takes at least two steps to unlock an account, and each step is a separate layer of security that an attacker must break. A stolen password alone no longer opens the account. Factors from different categories are what make it strong: a password and a security question are both things you know, so a scammer who tricks you into revealing one can trick you into revealing the other. In 2021 a ransomware gang shut down the Colonial Pipeline, which carries fuel to much of the US East Coast, after logging in with a single leaked password for an old account that did not use MFA.

    How does encryption keep data secret?

    Encryption is encoding data so that people without permission cannot read it. Decryption is decoding it back. Both use a key, a secret value that controls how the encoding works. There are two common approaches:

  • Symmetric key encryption uses one key for both encrypting and decrypting. Anyone who has the key can do both, so the sender and receiver have to share it safely.
  • Public key encryption uses a pair of keys. The public key, which anyone may have, encrypts. The matching private key, which only the receiver keeps, decrypts. The sender never needs the receiver's private key, but nobody can decrypt the message without it. Picture an open padlock that anyone can snap shut, while only you hold the key that opens it.
  • One of the oldest symmetric ciphers is the Caesar cipher: shift every letter a fixed number of places along the alphabet. The shift is the key, and the same key decrypts by shifting back.

    A Caesar cipher
    ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
    def caesar(message, key):
    """Shift each letter of an uppercase message by key places."""
    result = ""
    for letter in message:
    if letter in ALPHABET:
    position = (ALPHABET.index(letter) + key) % 26 # % 26 wraps Z back to A
    result += ALPHABET[position]
    else:
    result += letter # spaces and punctuation stay as they are
    return result
    secret = caesar("MEET ME AT THE LIBRARY", 3)
    print(f"Encrypted: {secret}")
    print(f"Decrypted: {caesar(secret, -3)}")
    Output
    Encrypted: PHHW PH DW WKH OLEUDUB
    Decrypted: MEET ME AT THE LIBRARY

    The Caesar cipher has a fatal weakness: there are only 25 useful keys. An attacker who intercepts a message can try every one of them in a fraction of a second and look for the one that produces real words.

    Breaking a Caesar cipher by trying every key
    ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
    def caesar(message, key):
    result = ""
    for letter in message:
    if letter in ALPHABET:
    result += ALPHABET[(ALPHABET.index(letter) + key) % 26]
    else:
    result += letter
    return result
    intercepted = "WKH TXLC LV RQ IULGDB"
    for key in range(1, 26):
    attempt = caesar(intercepted, -key)
    marker = " <-- real words!" if "THE" in attempt.split() else ""
    print(f"key {key:>2}: {attempt}{marker}")
    Output
    key  1: VJG SWKB KU QP HTKFCA
    key  2: UIF RVJA JT PO GSJEBZ
    key  3: THE QUIZ IS ON FRIDAY   <-- real words!
    key  4: SGD PTHY HR NM EQHCZX
    key  5: RFC OSGX GQ ML DPGBYW
    key  6: QEB NRFW FP LK COFAXV
    key  7: PDA MQEV EO KJ BNEZWU
    key  8: OCZ LPDU DN JI AMDYVT
    key  9: NBY KOCT CM IH ZLCXUS
    key 10: MAX JNBS BL HG YKBWTR
    key 11: LZW IMAR AK GF XJAVSQ
    key 12: KYV HLZQ ZJ FE WIZURP
    key 13: JXU GKYP YI ED VHYTQO
    key 14: IWT FJXO XH DC UGXSPN
    key 15: HVS EIWN WG CB TFWROM
    key 16: GUR DHVM VF BA SEVQNL
    key 17: FTQ CGUL UE AZ RDUPMK
    key 18: ESP BFTK TD ZY QCTOLJ
    key 19: DRO AESJ SC YX PBSNKI
    key 20: CQN ZDRI RB XW OARMJH
    key 21: BPM YCQH QA WV NZQLIG
    key 22: AOL XBPG PZ VU MYPKHF
    key 23: ZNK WAOF OY UT LXOJGE
    key 24: YMJ VZNE NX TS KWNIFD
    key 25: XLI UYMD MW SR JVMHEC

    Real encryption survives this attack because its number of possible keys is unimaginably large. Modern symmetric ciphers commonly use 128-bit or 256-bit keys, meaning 2 to the 128th or 2 to the 256th power possible keys. An older 56-bit standard was broken in 1998 by a machine built for the job, which is why keys grew. Even at a trillion guesses a second:

    Why key length matters
    GUESSES_PER_SECOND = 1_000_000_000_000 # a trillion keys a second
    SECONDS_PER_YEAR = 365 * 24 * 3600
    key_spaces = [
    ("Caesar cipher", 25),
    ("56-bit key", 2 ** 56),
    ("128-bit key", 2 ** 128),
    ("256-bit key", 2 ** 256),
    ]
    for name, keys in key_spaces:
    seconds = keys / GUESSES_PER_SECOND
    if seconds < 60:
    time_needed = f"{seconds:.1e} seconds"
    elif seconds < SECONDS_PER_YEAR:
    time_needed = f"{seconds / 3600:.0f} hours"
    else:
    time_needed = f"{seconds / SECONDS_PER_YEAR:.1e} years"
    print(f"{name:<14} {keys:.1e} keys: {time_needed} to try them all")
    print("The universe is about 1.4e+10 years old.")
    Output
    Caesar cipher  2.5e+01 keys: 2.5e-11 seconds to try them all
    56-bit key     7.2e+16 keys: 20 hours to try them all
    128-bit key    3.4e+38 keys: 1.1e+19 years to try them all
    256-bit key    1.2e+77 keys: 3.7e+57 years to try them all
    The universe is about 1.4e+10 years old.

    How does your browser know a public key really belongs to your bank and not to an impostor? Certificate authorities are trusted organizations that issue digital certificates, which confirm who owns the encryption keys used for secure communication. Your browser and phone come with a list of certificate authorities they trust. When a site presents its certificate, the browser checks that a trusted authority issued it before treating the https:// connection as secure. The system is a trust model: you trust the website because your browser trusts the authority that vouched for it.

    Check your understanding

    Which login process is an example of multifactor authentication?

    Answers

    Ana sends Ben a message using public key encryption. Which statement is accurate?

    Answers

    What is the role of a certificate authority?

    Answers

    A message is stored as a list of numbers from 0 to 25, one per letter. The code segment below encrypts it with a shift of 3. What is displayed?

    message ← [7, 24, 2]
    key ← 3
    FOR EACH n IN message
    {
    DISPLAY((n + key) MOD 26)
    }
    Answers
    Exercise 1: Caesar Cipher for Any Text
    Write Code

    Write caesar_encrypt(text, key) that shifts every letter of text by key places. Unlike the demo, it must handle both cases:

  • Uppercase letters stay uppercase and lowercase letters stay lowercase.
  • Spaces, digits and punctuation stay as they are.
  • key can be negative (to decrypt) or larger than 26.
  • caesar_encrypt("Meet at 9!", 1)  ->  "Nffu bu 9!"
    UPPER = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
    LOWER = "abcdefghijklmnopqrstuvwxyz"
    def caesar_encrypt(text, key):
    result = ""
    # Shift each letter, keep everything else
    return result
    Exercise 2: Count the Possible Passwords
    Write Code

    Write count_possible_passwords(password) that estimates how many passwords of the same length an attacker would have to try, based on the kinds of characters it uses:

  • any lowercase letter adds 26 possible characters
  • any uppercase letter adds 26
  • any digit adds 10
  • any other character (a symbol or a space) adds 33
  • Return the total number of possible characters raised to the power of the password's length.

    count_possible_passwords("Ab1")  ->  238328     (62 ** 3)
    def count_possible_passwords(password):
    characters = 0
    # Add 26, 26, 10 or 33 for each kind of character the password uses
    return characters ** len(password)

    How do attackers get in?

  • Malware is software meant to damage a computer system or take partial control of it. Ransomware locks your files until you pay; spyware secretly watches what you do.
  • A computer virus is a malicious program that can copy itself and get into a computer without permission. Viruses often attach themselves to legitimate programs and then start running on their own.
  • Phishing tries to trick you into handing over personal information, such as a password or a credit card number, usually with a message that looks like it came from a real company, school or friend. The attacker then uses that information to get into sensitive accounts like your bank or your email.
  • Keylogging is using a program that records every key a person presses, to capture passwords and other confidential information.
  • A rogue access point is a wireless access point that gives unauthorized access to a secure network, such as a Wi-Fi router someone plugs into a school's network without permission, which lets people nearby onto a network that is supposed to be locked down. Data sent over public networks can be intercepted, analyzed and even changed on the way, and a rogue access point is one way that happens. Attackers also set up hotspots with names like CoffeeShop_Free_WiFi, so that everything you send passes through their device.
  • Most attacks arrive through something you click or install:

  • A malicious link can be disguised on a web page or in an email: the text shows one address, but clicking goes somewhere else.
  • Unsolicited emails, attachments, links and forms can compromise a computer. They can come from strangers or from a friend whose account was hacked, so a familiar name does not prove a message is safe.
  • Untrustworthy downloads, often "free" copies of paid apps, game cheats and cracked software from freeware or shareware sites, can carry malware.
  • Before clicking a link, find where it really goes. The website is the name between // and the next /, and the part that matters is at the right end of that name.

    Where does the link really go?
    def real_site(url):
    """Return the website name in a link: the part between // and the next /."""
    after_slashes = url.split("//", 1)[-1]
    return after_slashes.split("/", 1)[0].lower()
    # (what the email shows, where the link actually points)
    links = [
    ("Sign in to your bank", "https://www.mybank.com/login"),
    ("https://www.mybank.com/login", "http://mybank.com.account-check.xyz/login"),
    ("Reset your school password", "https://login.myschool.edu/reset"),
    ]
    for shown, url in links:
    print(f"Shows: {shown}")
    print(f" Really goes to: {real_site(url)}")
    Output
    Shows: Sign in to your bank
      Really goes to: www.mybank.com
    Shows: https://www.mybank.com/login
      Really goes to: mybank.com.account-check.xyz
    Shows: Reset your school password
      Really goes to: login.myschool.edu

    The second link starts with your bank's name, but the site it opens ends in account-check.xyz, a stranger's site built to collect passwords.

    Ways to protect yourself and your devices:

  • Run antivirus and malware-scanning software, which helps protect a system against infection.
  • Install updates. Every real-world system has errors or design flaws that attackers can exploit, and updates fix them. In 2017 attackers stole personal data, including Social Security numbers, on about 147 million people from the credit agency Equifax through a flaw in its web software that had a fix available two months earlier.
  • Review app permissions. You control which data programs may collect. Check which apps can see your location, camera, microphone and contacts, and choose "only while using the app" or "never" wherever you can.
  • Exercise 3: Spot PII Before You Post
    Write Code

    Write has_pii(text) that returns True if a message contains an email address or a phone number, and False otherwise. Check each word (split on spaces) after stripping the characters .,!? from its ends:

  • An email address has exactly one @, at least one character before it, and a . somewhere after it.
  • A phone number is three groups of digits joined by dashes, with 3, 3 and 4 digits, like 555-867-5309.
  • has_pii("Call me at 555-867-5309 tonight")  ->  True
    has_pii("Meet at 5pm in room 204")          ->  False
    def has_pii(text):
    for word in text.split():
    word = word.strip(".,!?")
    # Return True if word is an email address or a phone number
    return False

    Check your understanding

    A program secretly installed on a library computer records everything typed on the keyboard, including the passwords people enter. What is this called?

    Answers

    Which two actions best protect a phone from attacks? Select two answers.

    Select 2 answers.

    Answers

    Exam topics: 5.6 Safe Computing (IOC-2.A, IOC-2.B, IOC-2.C)

    Related Tutorials

    Was this tutorial helpful?