Easier to read with cream paper, a tint, more contrast or larger text? Choose your colours and text, once, for every page.

Free lesson

Pseudonymisation and anonymous data

After this lesson: I can pseudonymise data and judge whether it is anonymous.

60 min lesson5 commandsMySQL and phpMyAdmin lab with a sample shop database to practise SQL

Is pseudonymised data anonymous?

Pseudonymisation replaces the details that name a person with a code, and keeps the list that links each code to its person somewhere else. Anonymous data is different: nobody can work out who anyone is.

The difference matters because pseudonymised data is still personal data, while truly anonymous data is not. The hard part is knowing which one you hold.

By the end of this lesson

Note

I can pseudonymise data and judge whether it is anonymous.

Key words

WordWhat it means
Pseudonymisationreplacing identifiers with a code
Tokenthe code that stands in for a person
Hasha fixed-length fingerprint of some text, hard to reverse
Anonymous datadata where nobody can work out who anyone is
Group sizehow many people share the same details
Re-identificationworking out who a record is about

The cells students fill in are left blank in this preview.

A token replaces the person

A research team studies what a library lends. It needs to see that the same reader borrowed three books. It does not need to know who the reader is.

So each reader gets a token. The loans table carries the token. The table that links tokens to readers is kept elsewhere, with tighter access.

Anyone who gets both tables can undo the change. That is why the result is still personal data.

Worked example: two tables, kept apart

TableHoldsWho may see it
Key tableReader 1 is token k7QpThe data owner only
Loans for researchToken k7Qp borrowed Tidal Charts in FebruaryThe research team
ReadersName, email, postcode, birth dateThe library staff

The cells students fill in are left blank in this preview.

A hash is a one-way fingerprint, but guessable

A hash function turns any text into a fixed string. The same text always gives the same string, and you cannot run it backwards.

There is a catch. If I guess an email, I can hash my guess and compare. So a plain hash of an email is weak.

Add a secret string in front, called a salt or pepper, that attackers do not know. Then a guess cannot be checked.

Hash one email address

Command
printf '[email protected]' | sha256sum

Shown here, not run. Create a free account to press Run and type it into your own lab’s terminal.

Hash it again with a secret in front

Command
printf '[email protected]' | sha256sum

Shown here, not run. Create a free account to press Run and type it into your own lab’s terminal.

What the two hashes show

The first Run prints a string that starts 33b3ccc1 and ends f35. The second prints one that starts a801524c. One added word changed every character.

That is why a hash makes a good token. Equal emails give equal tokens, so you can still count one reader's loans. A tiny change gives a completely different token.

A common mistake

Warning

Many people think pseudonymised data is anonymous. It is not. Whoever holds the key table, or can guess the input, can reverse it. Treat it as personal data. It is anonymous only when nobody can work out who anyone is.

Anonymous data needs big enough groups

Take the names out and look at what is left. Details such as area, age band and job can still be rare.

Count how many people share each combination. If one combination has a single person, that record can be traced to them.

A common aim is that every group holds at least a few people. The size you need depends on the harm if someone is found.

Accept the server's certificate

Command
printf '[client]\nssl-verify-server-cert=0\n' > ~/.my.cnf

Shown here, not run. Create a free account to press Run and type it into your own lab’s terminal.

Make a short name for the shop

Command
alias sql='mariadb -h db -u student -pstudent shop -t -e'

Shown here, not run. Create a free account to press Run and type it into your own lab’s terminal.

Find cities with a single customer

Command
sql "SELECT city, COUNT(*) AS people FROM customers GROUP BY city HAVING COUNT(*) = 1 ORDER BY city"

Shown here, not run. Create a free account to press Run and type it into your own lab’s terminal.

Try it: the smallest group

Code: sql
-- Group sizes by area and age band. Which group is smallest?
SELECT area, age_band, COUNT(*) AS people
FROM trips
GROUP BY area, age_band
ORDER BY people;
-- Remove age_band from SELECT and GROUP BY. Is the smallest group bigger?

A group of one can be traced

The Run prints two cities, Glasgow and Madrid, each with 1 customer. Anyone who knows a customer lives in Glasgow knows which row is theirs.

To fix a small group, make the detail broader (a country in place of a city) or remove that row from the shared data.

About this lab and its source: MySQL and phpMyAdmin lab with a sample shop database to practise SQL

Teaching a class? Set this module for your students with a teacher guide, marked assignments and a lab for every student.