Potwierdź mój wiek, anonimowo

Pojawiło się zagadnienie weryfikacji wieku przyjaznego dla prywatności czyli anonimowej weryfikacji wieku. Czyli mamy serwis X, który chce potwierdzić, że użytkownik ma 18 lat, ale jednocześnie ma otrzymać możliwie mało danych na temat tego użytkownika. Idealnie: tylko wiek.

Rysiek zaproponował rozwiązanie, które zaintrygowało mnie na tyle, że postanowiłem przeanalizować, czy to ma szansę działać. Wyszło mi, że nie. W tym wpisie skupiam się wyłącznie na proponowanym opisie algorytmu, czyli punktach i akapicie w którym jest zawarty.

Podsumowując założenia, ma tam być tak, że jest serwis X, użytkownik U, oraz serwis potwierdzania identyfikacji EID. X ma nie wiedzieć, kim jest U (dane osobowe). EID jak najbardziej zna dane osobowe użytkownika U, ma potwierdzić wiek, ale ma nie wiedzieć, że potwierdzenie jest na potrzeby serwisu X.

Problemy, które tu widzę, są dwa. Pierwszy jest taki, że użytkownik U w pełni kontroluje komunikację pomiędzy X a EID. Najpierw wysyła dane (które może dowolnie ustalić przed wysłaniem), potem otrzymuje odpowiedź, którą przekazuje. Czyli mamy do czynienia z man in the middle. Nie byłoby tu wielkiego problemu, gdyby EID wiedziało, że rozmawia z X – wystarczyłoby wtedy użyć odpowiednich kluczy prywatnych i publicznych. Ale jest to sprzeczne z założeniami.

Drugi problem jest poważniejszy. Serwis X nie wie, jakiego użytkownika weryfikuje. W tej sytuacji dowolny „dowód osobisty” może posłużyć do weryfikacji użytkownika.

Przekładając to na bardziej tradycyjne okoliczności: osoba w kominiarce przychodzi kupić alkohol i w ramach weryfikacji wieku pokazuje na ekranie telefonu zdjęcie dowodu osobistego. Czy sprzedawca jest w stanie zweryfikować wiek osoby na tej podstawie? Wg mnie – nie bardzo. Zdjęcie na ekranie to tutaj odpowiednik MITM (nie wiemy nawet, czy dowód jest autentyczny). Natomiast kominiarka (ukrycie tożsamości, anonimowość) uniemożliwia sprawdzenie, czy dowód należy do danej osoby.

Czyli dokładanie kolejnych warstw, algorytmów, systemów, stron w komunikacji nie zwiększa nam tu pewności anonimowej weryfikacji wieku. Nie w stosunku do wybrania przez użytkownika na stronie opcji „potwierdzam, że mam 18 lat”.

Być może po prostu mamy problem z akceptacją faktu, że weryfikacja wieku nigdy nie była anonimowa? Bo sprzedawca w sklepie z alkoholem nie tylko sprawdza[1], czy osoba posiada dowód osobisty. Sprawdza też, czy jest on autentyczny. I czy należy do tej osoby. OK, do tego ostatniego nie potrzebuje tu kompletu danych z dowodu, wystarczy zdjęcie. Ale do pozostałych danych ma dostęp w trakcie sprawdzania autentyczności.

Na Mastodonie trwa dyskusja, pewnie warto zapoznać się z całością, a komentować czy sugerować działające rozwiązania można równie dobrze tam.

[1] A przynajmniej powinien to robić.

Monero zdelegalizowane w Polsce?

Pozwoliłem sobie na mały clickbait w tytule, ale coś jest na rzeczy. Przynajmniej jeśli chodzi o Monero. We wpisie o wadach Bitcoin pisałem o ryzyku delegalizacji kryptowaluty. I wygląda, że częściowo, pomału się to ryzyko materializuje.

Logo Monero
Źródło: https://en.wikipedia.org/wiki/Monero#/media/File:Monero-Logo.svg

Co prawda nie chodzi o Bitcoina, a o Monero i parę innych kryptowalut, ale dzieje się. Binance delistuje 12 kryptowalut, w tym Zcash oraz Monero w 4 krajach. Chodzi o Polskę, Francję, Hiszpanię oraz Włochy.

Nie jest to oczywiście zupełna delegalizacja, bardziej utrudnienie obrotu. Jednak istnieją pomysły na wprowadzenie zakazu dla niektórych kryptowalut w całej Unii Europejskiej.

Wydarzenie uważam za godne odnotowania, może to być kamień milowy w historii kryptowalut.

Dlaczego k-anonimowość nie jest dobra przy hasłach?

Na z3s.pl pojawił się artykuł o tym, czym jest k-anonimowość. Jest to dobry artykuł i warto go przeczytać przed lekturą tego wpisu. Nie zgadzam się jedynie z tezą, że w przypadku haseł jest to bezpieczna metoda sprawdzania. Napisałem komentarz, ale pewnie nie wszyscy czytelnicy bloga tam trafią. Ponieważ bawię się z bazą hashy z HIBP i planuję wkrótce wpis na ten temat, uznałem, że jest dobra okazja do wstępu.

Moja teza jest taka, że w przypadku haseł k-anonimowość wcale nie jest taka bezpieczna, jak jest to przedstawiane. Zgodnie z artykułem obecnie dla hashy z bazy HIBP pierwsze 5 znaków występuje od 381 do 584. Czyli podczas sprawdzenia strona trzecia nie poznaje ani hasła, ani jego pełnego hasha. Przekazywane jest jedynie pierwszych 5 znaków hasha, czyli – tu moja interpretacja – ma jedynie 1/381 do 1/584 prawdopodobieństwo, że zna właściwy hash.

Gdyby przyjąć, że strona trzecia jest złośliwa, warto też przyjąć, że jest inteligentna. Czyli zamiast prawdopodobieństwa zwykłego użyje prawdopodobieństwa ważonego, uwzględniając ilość wystąpień danego hasha. Dla przykładu z artykułu na z3s.pl i hasła P@ssw0rd mamy zwracanych 543 różnych hashy:

curl -s https://api.pwnedpasswords.com/range/21BD1 | wc -l

Natomiast suma wystąpień wszystkich hashy w momencie pisania tego wpisu wynosi 60808.

curl -s https://api.pwnedpasswords.com/range/21BD1 | awk -F ":" '{sum += $2} END {print sum}'

Nasz hash wystąpił 52579 razy. Znając zwyczaje ludzi dotyczące haseł i stosując prawdopodobieństwo ważone uzyskujemy 86% szansę na to, że chodzi o hash należący do hasła P@ssw0rd. Pewności nie ma, ale z 1/543 czyli z ~0,18% robi się 86%, czyli jakieś 467 razy więcej. Ups!

Oczywiście nie znamy tu samego hasła. Znamy jedynie – a i to jedynie ze sporym prawdopodobieństwem – jego hash. O tym, że to niekoniecznie jest problem, może będzie w którymś kolejnym wpisie.

W każdym razie gdybym był serwisem, to bałbym się odpytywać serwis trzeci o hashe haseł moich użytkowników. Użytkowników podejrzewam o proste, słownikowe hasła, jakiś serwis trzeci. Zwłaszcza jeśli ten serwis ma/może mieć także inne informacje, które pozwalają mu ustalić kto pyta o hasło. Tak właśnie może być w przypadku Cloudflare, który może dostawać część ruchu od użytkownika w ramach CDN, DNS lub DoH. Prosta korelacja czasowa może w tym przypadku prowadzić do powiązania hasha hasła z IP użytkownika. Jeśli chcemy sprawdzać hasła, to lepszym rozwiązaniem jest stworzenie lokalnej kopii bazy którą pobierzemy z HIBP.

Co nie znaczy oczywiście, że k-anonimowość ogólnie nie spełnia swojego zadania. Po prostu mam wrażenie, że akurat w przypadku hashy hasła i tej konkretnej implementacji nie jest tak bezpieczna, jak jest to przedstawiane.

Warto też zauważyć, że hasło z którym mamy tu do czynienia jest proste/populare. Dla innych pięcioznakowych początków hashy wystąpienia mogą rozkładać się inaczej, bez tak silnego wskazania na konkretny hash.

UPDATE Tak naprawdę nie ma potrzeby używania całej bazy hashy i ilości ich wystąpień z HIBP (>20GB). Najczęściej występujące 100 tys. hashy to raptem 3,2 MB. Najczęstszy milion – 32 MB.