Hej, miło mi, że ktoś to czyta :)

System został zaprojektowany od podstaw z myślą o bezpieczeństwie. Pierwsze zabezpieczenia wchodzą w grę już na etapie logowania. Użytkownik, logując się, nie przesyła swojego hasła na serwer. Zamiast tego strona wykorzystuje protokół OCAKE . Jak to działa? Serwer generuje jednorazowe "wyzwanie" dla klienta, a klient na podstawie hasła tworzy odpowiedź. Po weryfikacji odpowiedzi serwer wie, że użytkownik zna hasło, ale nigdy go nie widział. Dzięki temu nawet w przypadku podsłuchu komunikacji lub przejęcia serwera, hasło pozostaje bezpieczne. Celem zapewnienia PQ-safe wymieniliśmy Dh w protokole SRP na Krystars Kyber. Czy jest to idealne nie, czy jest to robienie własnego crytpo tak, czy mamy jakiś wybór nie za badzo, bo nie ma protokołu quantum safe np. OPQQUE też nie jest Quantum safe a implementacje społeczności są takimi samymi prototypami jak nas. Czy jesteśmy z tego dumni nie, ale nie mamy wyjścia. Omówienie protokołu logowania
rejestracja
1. Użytkownik generuje salt
2. użytkownik na podstawi salta i hasła generuje ziarno
3. na podstawnie p.2 klient geenruje pare kluczy
3. zapisuje sól i klcuz publiczny na serweże
do tego momentu nie ma dużych różnic od SRP poza algorytmem. No musze wymienić ;)
logowanie.
1. server generuje jednorazowy klucz
2. generuje kapsułe bazując na kluczu publicznym klienta
3. server wysyła do klienta jednorazowy klucz, statyczną sul i losowe wyzwanie
4. client generuje z hasła i soli generuje pare kluczy
4. client generuje kapsułe i współdzielony sekret z jednorazowego klucza serwera
5. client generuje dekapsułuje shared secret od serwera
6. client generuje ostateczny secret HASH(sharedsecret1+sharedsecret2)
7. client oblicza odpowiedź HMAC(wyzwanie, ostateczny sektret)
8. client generuje wyzwanie servera
9. client przesyła na server odpowiedź, kapsułe i wyzwanie serwera
10. server dekapułuje kapsułe
12. server ostateczny sekret = HAsh(sharedsecret1+sharedsecret2)
13. serwer weryfikuje odpowiedź clienta
14. server generuje odpowiedź dla klienta HMAC(wyzwanie servera, ostateczny sektret)
15. serwer odsyła klientowi odpowiedź
16. client weryfikuje odpowiedż
To jest bardzo prosty protokół angażująćy 2 funkcje KEM i HASH. Prostota nic nie gwarantuje ale przynajmniej nie robiłem włąsnych "klocków" tylko je skłądam co jest zdecydowanie lepszym pomysłem mimo że wciąż nie idealnym

Protokół Logowania (Diagram)

Aby lepiej zobrazować proces logowania, poniżej przedstawiamy uproszczony diagram przepływu:

Szczegółowy opis kroków znajduje się w tekście powyżej.

Dlaczego to ważne?

Nawet jeśli atakujący przejmie serwer, nie uzyska dostępu do haseł. Kolejnym elementem jest pełna infrastruktura PKI (Public Key Infrastructure). Podczas pierwszego logowania generowane są dwie pary kluczy w standardzie CRYSTALS-Kyber oraz CRYSTALS-Dilithium (algorytmy postkwantowe co jest zgodne z FIPS 204, FIPS 203 oraz zaleceniami NIST co do twożenia nowych systemów dla wyturców systemów dla rządu USA przetważające dane poufne ponieważ dane poufne muszą być tajne przez conajmniej 10 lat). Jest to moja implementacja biblioteki liboqs w JavaScript przy użyciu WebAssembly (WASM). Nie modyfikowałem kodu samej biblioteki, a jedynie importy, więc nie powinno to wpłynąć na bezpieczeństwo.

Klucze są szyfrowane hasłem za pomocą algorytmu Argon2id z parametrami: 500 MB pamięci, 3 iteracje, równoległość 2. Te parametry zostały starannie dobrane, aby zapewnić wysoki poziom bezpieczeństwa przy jednoczesnym zachowaniu akceptowalnego czasu logowania dla użytkownika. 500 MB pamięci utrudnia ataki brute-force wykorzystujące akceleratory sprzętowe (np. GPU) i ASIC, ponieważ wymagają one dużej ilości pamięci RAM. 3 iteracje i równoległość 2 dodatkowo zwiększają koszt obliczeniowy ataku, jednocześnie utrzymując czas szyfrowania na poziomie około 3 sekund. Taki czas opóźnienia skutecznie chroni przed masowymi atakami brute-force, gdzie atakujący próbuje złamać wiele haseł jednocześnie.

Salt jest losowym ciągiem znaków powiązanym z użytkownikiem, co dodatkowo utrudnia ataki słownikowe i tęczowe tablice.

Zabezpieczenia kluczy i sesji

Po odszyfrowaniu klucza jest on zabezpieczany kluczem sesji przechowywanym na serwerze oraz w indexedDB z flagą exportable: false. Sesja jest ważna przez 4 godziny, po czym wygasa. Ciasteczka (cookies) są zabezpieczone flagami Secure, HttpOnly oraz SameSite=Strict. Sesja jest zarządzana przez backend w C#. Gdy sesja wygaśnie, w przeglądarce nie pozostają żadne wrażliwe dane.

Weryfikacja kluczy i zaufanie

Każdy użytkownik ma dostęp do kluczy publicznych innych użytkowników, ale zalecam ręczną weryfikację odcisku klucza poprzez przycisk "Pokaż klucze". W tej funkcji zostanie wyświetlony odcisk palca klucza do podpisów innego użytkownika. Jeśli użytkownik go zweryfikuje, może kliknąć przycisk “zaufaj”, co spowoduje podpisanie przez niego klucza drugiej osoby, co w oczach systemu oznaczy go jako “zaufany”.

Mechanizmy ochrony przed podmianą kluczy

Co jednak, jeśli serwer podmieni klucz użytkownika? Do ochrony przed tym mamy dwa mechanizmy:

  1. Serwer nie zna hasła, więc nie może zaszyfrować klucza tajnego (używamy AES, czyli szyfru symetrycznego).
  2. Przy każdym logowaniu wyświetlane jest 8 emotek symbolizujących około 10 pierwszych bajtów odcisku palca klucza publicznego Dilithium. Użytkownik w dowolnym momencie może wyświetlić pełny odcisk palca, ale emotki służą jako szybkie skojarzenie, że wszystko jest w porządku. Jeśli użytkownik zauważy zmianę emotek, będzie wiedział, że jego klucz został podmieniony.

Zaufanie między użytkownikami

Zaufanie między użytkownikami odbywa się poprzez porównanie pełnego odcisku SHA256. Użytkownikom wyświetlany jest odcisk bez ostatnich 5 znaków, a celem weryfikacji jest wprowadzenie tych brakujących znaków. Jeśli się zgadzają, klient podpisuje swoim kluczem tożsamości klucz drugiej strony. Dzięki temu użytkownik wie, że klucz drugiej strony się nie zmienił.

Forward Secrecy (FS)

Co do Forward Secrecy (FS), istnieje możliwość rotacji klucza Kyber w dowolnym momencie. Po rotacji klucz jest podpisany kluczem Dilithium, więc zaufanie nie jest naruszone, ponieważ zaufanie dotyczy kluczy Dilithium. Klucze Kyber są przechowywane na serwerze jako archiwalne, aby umożliwić dostęp do starych wiadomości.

Integracja z HIBP

Dzięki integracji z HIBP (Have I Been Pwned) sprawdzamy, czy hasło nie wyciekło. Wysyłamy jedynie 5 pierwszych znaków hasha hasła, a HIBP zwraca pasujące sufiksy. Dzięki temu ani my, ani HIBP nie znamy pełnego hasła.

Inne zabezpieczenia

Struktura Uprawnień

Administrator
  • Wszystkie wiadomości (nie szyfrowane) Odczyt/Modyfikacja
  • Wszystkie opinie Odczyt/Modyfikacja
  • Wszystkie oznaczone notatki Odczyt
  • Wszystkie zajęcia Odczyt/Modyfikacja
  • Wszystkie instancje zajęć Odczyt/Modyfikacja
  • Wszystkie współdzielone notatki Odczyt
  • Wszystkie obecności Odczyt/Modyfikacja
  • Użytkownicy Odczyt/Modyfikacja
Kadrowa
  • Użytkownicy Odczyt/Modyfikacja
  • Wszystkie RCP / urlopy Odczyt/Modyfikacja
Przełożony
  • Wszystkie RCP / urlopy (swoich podwładnych) Odczyt/Modyfikacja
Nauczyciel
  • Wszystkie opinie Odczyt/Modyfikacja
  • Wszystkie zajęcia Odczyt
  • Swoje zajęcia Odczyt/Modyfikacja
  • Swoje instancje zajęć Odczyt/Modyfikacja
  • Swoje RCP/ Uropy (edycja tylko nie zatwierdzonych) Odczyt/Modyfikacja
  • swoje i udostępnione notatki Odczyt
Rodzic
  • Swoje zajęcia Odczyt + możliwość odwołania
  • Swoje instancje zajęć Odczyt
Zalogowany Użytkownik
  • Swoje wiadomości (rodzic nie widzi daty odczytania) Odczyt
  • Wszyscy użytkownicy Odczyt