Dokumentacja Shadowsocks
Nawigacja
AEAD
AEAD oznacza uwierzytelnione szyfrowanie z powiązanymi danymi. Szyfry AEAD zapewniają jednocześnie poufność, integralność i autentyczność. Mają doskonałą wydajność i efektywność energetyczną na nowoczesnym sprzęcie. Użytkownicy powinni używać szyfrów AEAD, gdy tylko jest to możliwe.
Zalecane są następujące szyfry AEAD. Zgodne implementacje Shadowsocks muszą obsługiwać AEAD_CHACHA20_POLY1305. Implementacje dla urządzeń ze sprzętową akceleracją AES powinny również implementować AEAD_AES_128_GCM i AEAD_AES_256_GCM.
Imię | Alias | Rozmiar klucza | Rozmiar soli | Rozmiar jednorazowy | Rozmiar znacznika |
AEAD_CHACHA20_POLY1305 | chacha20-ietf-poly1305 | 32 | 32 | 12 | 16 |
AEAD_AES_256_GCM | aes-256-gcm | 32 | 32 | 12 | 16 |
AEAD_AES_128_GCM | aes-128-gcm | 16 | 16 | 12 | 16 |
Sprawdź Rejestr IANA AEAD dla schematu nazewnictwa i specyfikacji.
Wyprowadzenie klucza
Klucz główny można wprowadzić bezpośrednio od użytkownika lub wygenerować na podstawie hasła.
HKDF_SHA1 to funkcja, która pobiera tajny klucz, nie-tajną sól, ciąg informacji i tworzy podklucz, który jest silny kryptograficznie, nawet jeśli wejściowy tajny klucz jest słaby.
HKDF_SHA1(klucz, sól, informacje) => podklucz
Ciąg informacji wiąże wygenerowany podklucz z określonym kontekstem aplikacji. W naszym przypadku musi to być ciąg „ss-subkey” bez cudzysłowów.
Uzyskujemy podklucz na sesję ze wstępnie współdzielonego klucza głównego przy użyciu HKDF_SHA1. Sól musi być unikalna przez cały okres użytkowania wstępnie udostępnionego klucza głównego.
Uwierzytelnione szyfrowanie/odszyfrowywanie
AE_encrypt to funkcja, która pobiera tajny klucz, nie-tajny identyfikator jednorazowy, wiadomość i tworzy tekst zaszyfrowany oraz tag uwierzytelniający. Nonce musi być unikalne dla danego klucza w każdym wywołaniu.
AE_encrypt(klucz, wartość jednorazowa, wiadomość) => (tekst zaszyfrowany, znacznik)
AE_decrypt to funkcja, która pobiera tajny klucz, non-secret nonce, tekst zaszyfrowany, tag uwierzytelniający i tworzy oryginalną wiadomość. Jeśli jakiekolwiek dane wejściowe zostaną naruszone, odszyfrowanie zakończy się niepowodzeniem.
AE_decrypt(klucz, wartość jednorazowa, tekst zaszyfrowany, znacznik) => wiadomość
TCP
Strumień TCP zaszyfrowany przez AEAD rozpoczyna się od losowo wygenerowanej soli w celu uzyskania podklucza na sesję, po którym następuje dowolna liczba zaszyfrowanych fragmentów. Każdy fragment ma następującą strukturę:
[długość zaszyfrowanego ładunku][znacznik długości][zaszyfrowany ładunek][tag ładunku]
Długość ładunku to 2-bajtowa liczba całkowita bez znaku typu big-endian ograniczona do 0x3FFF. Wyższe dwa bity są zarezerwowane i muszą być ustawione na zero. Ładowność jest zatem ograniczona do 16*1024 – 1 bajt.
Pierwsza operacja szyfrowania/odszyfrowywania AEAD wykorzystuje zliczanie nonce, zaczynając od 0. Po każdej operacji szyfrowania/deszyfrowania, liczba jednorazowa jest zwiększana o jeden, tak jakby była to liczba całkowita little-endian bez znaku. Należy zauważyć, że każda porcja TCP obejmuje dwie operacje szyfrowania/odszyfrowywania AEAD: jedną dla długości ładunku i jedną dla ładunku. Dlatego każdy fragment zwiększa liczbę jednorazową dwukrotnie.
TCP
Strumień TCP zaszyfrowany przez AEAD rozpoczyna się od losowo wygenerowanej soli w celu uzyskania podklucza na sesję, po którym następuje dowolna liczba zaszyfrowanych fragmentów. Każdy fragment ma następującą strukturę:
[długość zaszyfrowanego ładunku][znacznik długości][zaszyfrowany ładunek][tag ładunku]
Długość ładunku to 2-bajtowa liczba całkowita bez znaku typu big-endian ograniczona do 0x3FFF. Wyższe dwa bity są zarezerwowane i muszą być ustawione na zero. Ładowność jest zatem ograniczona do 16*1024 – 1 bajt.
Pierwsza operacja szyfrowania/odszyfrowywania AEAD wykorzystuje zliczanie nonce, zaczynając od 0. Po każdej operacji szyfrowania/deszyfrowania, liczba jednorazowa jest zwiększana o jeden, tak jakby była to liczba całkowita little-endian bez znaku. Należy zauważyć, że każda porcja TCP obejmuje dwie operacje szyfrowania/odszyfrowywania AEAD: jedną dla długości ładunku i jedną dla ładunku. Dlatego każdy fragment zwiększa liczbę jednorazową dwukrotnie.