Bezpieczeństwo · Szczegółowo
Pełny cykl życia kryptografii
Dokładny przegląd tego, co dzieje się z twoimi danymi na każdym etapie — z prymitywami, parametrami i granicami zaufania wyłożonymi wprost. Każdy krok zaczyna się od podsumowania prostym językiem, więc możesz czytać na takim poziomie szczegółowości, jaki ci odpowiada.
Krok 01 · Szyfrowanie
Twój sekret jest pieczętowany na twoim urządzeniu
Prościej mówiąc: szyfrowanie odbywa się w twojej przeglądarce, zanim cokolwiek zostanie wysłane. To, co otrzymujemy, jest już nieczytelne.
Gdy naciskasz Zaszyfruj, przeglądarka losuje z WebCrypto CSPRNG nowy 256-bitowy klucz treści i szyfruje twoje dane algorytmem AES-256-GCM. GCM jest szyfrowaniem uwierzytelnionym: każdy fragment ma 128-bitowy znacznik, więc każda późniejsza manipulacja zostaje wykryta, zamiast zostać po cichu odszyfrowana.
Tekst i pliki są traktowane identycznie — jedne i drugie stają się jednym nieprzejrzystym binarnym blobem, dopełnionym do standardowego rozmiaru, tak że krótkie hasło i mały plik wyglądają tak samo. Tekst jawny nigdy nie trafia do sieci i nigdy nie opuszcza pamięci karty.
Krok 02 · Przechowywanie klucza
Klucz ukrywa się w linku, nie na naszych serwerach
Prościej mówiąc: część linku po znaku # zawiera klucz — a przeglądarki nigdy nie wysyłają tej części do żadnego serwera.
Twój link zawiera losowe 256-bitowe ziarno we fragmencie adresu URL — wszystkim, co następuje po znaku #. Zgodnie ze specyfikacją URL przeglądarka odcina fragment i nigdy nie dołącza go do żądania wysyłanego do naszych serwerów. Z tego ziarna przeglądarka wyprowadza za pomocą HKDF wartość wyszukiwania, służącą do odnalezienia sekretu, oraz klucz, który odpakowuje klucz treści. Serwer widzi wyłącznie skrót wartości wyszukiwania.
Przeglądarka odbiorcy odczytuje ziarno z fragmentu i lokalnie wykonuje to samo wyprowadzenie. Właśnie to oznacza tutaj „zero-knowledge”: sam szyfrogram jest bezużyteczny bez linku.
Krok 03 · Opcjonalne hasło
Drugi zamek, który znają tylko ludzie
Prościej mówiąc: dodaj hasło, a nawet ktoś z pełnym linkiem nie otworzy sekretu bez niego.
Jeśli ustawisz hasło, zostanie ono wzmocnione funkcją Argon2id — funkcją wyprowadzania klucza wymagającą dużo pamięci — i połączone z ziarnem w klucz, który opakowuje klucz treści. Samo hasło nigdy nie jest przesyłane ani przechowywane; znasz je tylko ty i odbiorca. Błędne próby są powtarzane w przeglądarce odbiorcy na danych, które już ma, więc serwer nie może ich policzyć.
Duże wymagania pamięciowe sprawiają, że masowe zgadywanie offline jest kosztowne nawet na GPU i układach ASIC. Przekaż hasło innym kanałem niż link, a oba składniki nigdy nie spotkają się w jednym miejscu. Moduł Argon2 jest pobierany przy każdym tworzeniu i odsłanianiu sekretu, więc z ruchu sieciowego nie da się odczytać, które sekrety mają hasło.
Krok 04 · Transmisja & przechowywanie
Twoje urządzenie opuszcza wyłącznie szyfrogram
Prościej mówiąc: przechowujemy zamknięte pudełko i czas wygaśnięcia. Nic więcej — żadnego tekstu jawnego, żadnego klucza, żadnych danych o tobie.
Blob jest przesyłany przez TLS i przechowywany jako szyfrogram obok zahaszowanych danych uwierzytelniających, swojego trybu ważności i zaokrąglonego czasu wygaśnięcia. Celowo nie przechowujemy tożsamości nadawcy, odbiorcy, logów IP, czasu utworzenia ani historii dostępu. Nie ma systemu kont, który wiązałby sekret z osobą. Ograniczanie liczby żądań działa na HMAC adresu z rotowaną solą, więc niczego sprzed rotacji nie da się powiązać z niczym po niej.
Ponieważ przechowywany obiekt nie ma znaczenia bez ziarna z fragmentu, włamanie na serwer lub nakaz sądowy dają jedynie nieprzejrzyste bajty i skróty, których nie da się zamienić z powrotem w nic.
Krok 05 · Odbiór & zniszczenie
Wygrywa pierwszy odczyt — potem sekret jest kasowany
Prościej mówiąc: otwarcie jednorazowego linku jeden raz wydaje pudełko i usuwa kopię z serwera. Możesz też samodzielnie zniszczyć sekret, w dowolnej chwili.
Gdy strona odsłaniania się ładuje, nic nie jest pobierane: żądanie wychodzi dopiero po prawdziwym kliknięciu lub naciśnięciu klawisza, więc skanery linków i podglądy na czatach nie mogą zużyć sekretu. W przypadku jednorazowego sekretu serwer zajmuje wiersz jedną warunkową aktualizacją — wygrywa dokładnie jedno żądanie — i od tej chwili sekret uznaje się za zużyty. Jeśli połączenie zostanie zerwane, ta sama przeglądarka może pobrać dane ponownie w ciągu 15 minut; nikt inny nie może, a niepotwierdzone zajęcie kończy się zniszczeniem, nigdy cofnięciem. Sekrety czasowe są zwykłym odczytem aż do wygaśnięcia.
Każdy sekret ma też prywatny link do spalenia. Samo jego otwarcie niczego nie niszczy; potwierdzenie natychmiast kasuje szyfrogram — zanim jakikolwiek odbiorca zdąży go przeczytać.
Model zagrożeń
Co shhnote widzi, a czego nie
Uczciwa wersja. Oto dokładnie, gdzie przebiega granica zaufania.
Nigdy nie opuszcza twojego urządzenia
Czego nie widzimy
Twój tekst jawny · klucz treści i ziarno · twoje hasło · czy ustawiono hasło · kto utworzył lub otworzył sekret · kiedy go utworzono · logi dostępu na poziomie IP. Nic z tego nie jest przesyłane ani przechowywane.
Przechowywane na naszych serwerach
Co faktycznie mamy
Zaszyfrowany blob, którego nie możemy otworzyć · jego klasę rozmiaru po dopełnieniu · jednokierunkowe skróty wartości, których twoja przeglądarka używa, aby go odnaleźć lub spalić · informację, czy jest jednorazowy, czy czasowy · zaokrąglony czas wygaśnięcia. Wszystko to jest bezużyteczne bez ziarna z twojego linku.
Warto wiedzieć
Uczciwe zastrzeżenia
Każdy, kto ma pełny link (i hasło, jeśli je ustawiono), może przeczytać jednorazowy sekret — traktuj sam link jak sekret. Po wyświetleniu sekretu strona nadpisuje przy wyjściu to, co może, ale JavaScript nie daje na to gwarancji; zamknij kartę, gdy skończysz. Przeglądarka sterowana automatycznie, która wprowadza prawdziwe zdarzenia wejścia, może otworzyć jednorazowy sekret tak jak człowiek — odbiorca nie znajdzie wtedy niczego, co jest uczciwym wynikiem. Usunięcie sekretu kasuje rekord; zaszyfrowane pozostałości mogą przetrwać w dziennikach, wolnym miejscu na dysku lub kopiach zapasowych, dopóki nie zostaną nadpisane, jako szyfrogram bez klucza. Duże sekrety przechowywane poza bazą danych niosą czas zapisania pliku. I jak w każdej aplikacji internetowej ufasz kodowi dostarczonemu do twojej przeglądarki — dlatego shhnote jest open source i można go hostować samodzielnie.
Specyfikacja kryptograficzna
Wszystkie prymitywy w jednym miejscu
Szyfrowanie
Uwierzytelnione szyfrowanie symetryczne we fragmentach po 64 KiB. 256-bitowy klucz plus znacznik integralności dla każdego fragmentu, więc manipulacja lub obcięcie zostaje wykryte — a nie tylko kończy się nieczytelnymi danymi.
Wyprowadzanie klucza
Klucze i identyfikatory powstają z ziarna przez HKDF-SHA-256. Opcjonalne hasła są wzmacniane funkcją KDF wymagającą dużo pamięci, przez co brute-force offline jest powolny i kosztowny nawet na dedykowanym sprzęcie.
Losowość
Ziarna, klucze, sole i wartości nonce pochodzą z kryptograficznie bezpiecznego generatora przeglądarki. Nigdy Math.random(), nigdy nic przewidywalnego.
Przechowywanie klucza
Ziarno znajduje się w twoim linku po znaku #. Przeglądarki nigdy nie przesyłają fragmentu, więc nigdy nie trafia on na nasze serwery.
W transmisji
Twoje urządzenie opuszcza wyłącznie szyfrogram, przesyłany przez nowoczesny TLS. Otrzymujemy nieprzejrzysty blob, którego nie możemy otworzyć.
W spoczynku
Zapisujemy zaszyfrowany blob, jednokierunkowe skróty jego danych uwierzytelniających i zaokrąglony czas wygaśnięcia — żadnego tekstu jawnego, żadnych kluczy, żadnych metadanych o nadawcy czy odbiorcy.
FAQ techniczne
Dla dbających o bezpieczeństwo
Jak gwarancja jednorazowości jest chroniona przed wyścigami?
Odsłonięcie wykonuje jedną warunkową aktualizację, która przestawia wiersz ze stanu „aktywny” na „zajęty”. Dwa równoczesne żądania nie mogą się powieść jednocześnie; drugie widzi już zajęty rekord i dostaje tę samą odpowiedź „nie znaleziono sekretu” co każdy inny. Zajęcia nigdy się nie cofa: jeśli pobieranie się nie powiedzie, posiadacz tokenu zajęcia pobiera dane ponownie w wyznaczonym oknie czasowym, a w przeciwnym razie sekret zostaje zniszczony nieprzeczytany.
Dlaczego fragment URL, a nie parametr zapytania?
Parametry zapytania są wysyłane do serwera i trafiają do logów dostępu, serwerów proxy i narzędzi analitycznych. Fragment (po znaku #) zgodnie ze specyfikacją URL pozostaje po stronie klienta — przeglądarka nigdy nie umieszcza go w żądaniu HTTP. Na tej właściwości opiera się cały model zero-knowledge. Po odsłonięciu strona usuwa też fragment z paska adresu i historii.
Co chroni jednorazowe sekrety przed przedwczesnym spaleniem przez skanery linków?
Strona wyświetlania to ten sam statyczny dokument dla każdego sekretu i przy ładowaniu niczego nie pobiera. Żądanie jest wysyłane dopiero po zaufanym kliknięciu lub naciśnięciu klawisza — skryptowe click() ani wysłanie formularza się nie liczą. Automatyczne skanery (filtry poczty, podglądy linków na czatach, antywirusy) wczytują zawsze tylko tę statyczną powłokę.
Czy mogę to zweryfikować lub hostować samodzielnie?
Tak. Pełny kod źródłowy jest publiczny na licencji AGPLv3, protokół jest opisany w specyfikacji z wektorami zgodności, względem których każda implementacja może się sprawdzić, jest też przewodnik po własnej instalacji. Możesz przeanalizować kryptografię po stronie klienta i uruchomić własną instancję, tak by granica zaufania była w całości twoja.
Czy coś jest logowane w celu zapobiegania nadużyciom?
Nie prowadzimy logów dostępu do poszczególnych sekretów ani historii adresów IP. Ograniczanie liczby żądań korzysta z kluczowanego skrótu adresu z solą, która jest rotowana i przy każdej rotacji zeruje wszystkie liczniki. Zgłoszenia nadużyć są liczone dziennie; nie ma zapisu, który sekret został zgłoszony.
Wskazówki dotyczące bezpiecznego udostępniania
- Wyślij hasło inną drogą niż link, na przykład link e-mailem, a hasło przez telefon.
- Wybierz najkrótszy czas wygaśnięcia, który ci wystarczy.
- Używaj jednorazowego sekretu do haseł i innych informacji, które powinny zostać przeczytane dokładnie raz.
Zgłaszanie podatności
Jeśli trafisz na problem z bezpieczeństwem tej strony, napisz na [email protected] i poinformuj nas poufnie, zanim powiesz o tym komukolwiek innemu. Opisz, co udało ci się znaleźć i jak to odtworzyć.
Zobowiązujemy się:
- odpowiedzieć w ciągu 5 dni roboczych;
- informować cię na bieżąco w trakcie naprawy;
- wymienić cię przy publikacji poprawki, jeśli sobie tego życzysz.
Podczas testów nie uzyskuj dostępu do danych innych osób, nie zakłócaj działania usługi i nie uruchamiaj automatycznych skanów, które mocno ją obciążają.
Podatności w samym oprogramowaniu shhnote: zobacz politykę bezpieczeństwa projektu.
Wypróbuj — zajmie ci to dziesięć sekund
Napisz coś tajnego, odbierz jednorazowy link i zobacz, jak sekret znika.