Jak wybrać odpowiedni IV (Wektor inicjalizacji) dla AES/CTR/NoPadding?

Chciałbym zaszyfrować pliki cookie, które są napisane przez webapp i chciałbym utrzymać rozmiar plików cookie do minimum, stąd powód wybrałem AES / CTR / NoPadding.

Co polecacie używać jako IV, który jest wystarczająco losowy i nadal utrzymuje aplikację bez statusu. Wiem, że mogę wygenerować losową kroplówkę i dołączyć ją do wiadomości, ale to zwiększy rozmiar pliku cookie.

DODATKOWO, jaki jest zalecany rozmiar IV dla 128-bitowego AES?

Jak czy wszyscy to robią? Czy istnieją jakieś" wypróbowane i prawdziwe " sposoby? Nie chcę odkrywać koła na nowo.

Author: Artjom B., 2011-01-05

5 answers

CTR security wymaga, aby nigdy ponownie używać IV do szyfrowania dwóch wiadomości z tym samym kluczem. W rzeczywistości jest to jeszcze bardziej surowsze: tryb CTR działa poprzez szyfrowanie kolejnych wartości licznika (IV jest tylko wartością początkową dla tego licznika), a odpowiednie bezpieczeństwo jest osiągane tylko wtedy, gdy ta sama wartość licznika nie jest używana dwukrotnie; oznacza to, że szyfrowanie wartości z IV faktycznie "zużywa" ciąg kolejnych wartości IV, które nie mogą być ponownie użyte z innym licznikiem. szyfrowanie.

Najprostszym sposobem na to jest użycie zabezpieczonego kryptograficznie generatora liczb losowych i utworzenie nowego 16-bajtowego losowego IV dla każdej wiadomości. Podkreślam "bezpieczeństwo kryptograficzne", ponieważ to ważne; podstawowy generator liczb losowych nie wystarczy. W Javie użyj java.util.SecureRandom. Z Win32 wywołaj CryptGenRandom(). Przy przypadkowym wyborze przestrzeń możliwego 128-bitowego IV jest na tyle duża, że kolizje są niezwykle nieprawdopodobne. Właśnie dlatego AES wykorzystuje 128-bitowe bloki (tak 128-bitowe IV).

Jednostka, która odszyfruje wiadomość, musi znać IV, więc musisz ją przechowywać razem z zaszyfrowaną wiadomością. To dodatkowe 16 bajtów. Rozumiem, że ten overhead jest tym, czego chcesz uniknąć, chociaż 16 bajtów to nie tyle za ciasteczko. Efektywna maksymalna długość pliku cookie zależy od przeglądarki internetowej, ale 4000 znaków wydaje się działać "wszędzie". 16-bajtowy IV, zakodowany w postaci znaków (np. z Base64), będzie używał około 22 znaków, tj. znacznie mniej niż 1% maksymalnego rozmiaru plików cookie: może stać Cię na to ?

Teraz możemy dostać funky i spróbować zmniejszyć długość IV poprzez trickery:

  • Wygeneruj IV za pomocą funkcji hash: Po stronie serwera użyj licznika, który zaczyna się od 0 i jest zwiększany za każdym razem, gdy potrzebna jest nowa IV. Aby uzyskać IV, hashujesz licznik za pomocą odpowiedniej funkcji skrótu, np. SHA-256, i zachowujesz pierwsze 16 bajtów wartości skrótu. "Właściwości randomizacji" funkcja hash będzie wystarczająca, aby IV był wystarczająco losowy w odniesieniu do wymagań CTR. Wymaga to kryptograficznie bezpiecznej funkcji skrótu, stąd SHA-256 (unikaj MD5). Następnie wystarczy zapisać wartość licznika w pliku cookie, a licznik będzie krótszy niż 16 bajtów (np. jeśli masz nie więcej niż 4 miliardy klientów, licznik zmieści się w 4 bajtach). Istnieje jednak ukryty koszt: serwer (przypuszczam, że serwer wykonuje szyfrowanie w Twoim systemie) musi się upewnić że nigdy nie wykorzystuje ponownie wartości licznika, więc musi przechowywać" aktualny licznik " gdzieś w sposób, który utrzymuje się przez restart serwera, a także nie zawiedzie, jeśli skalujesz do kilku front-endów. To nie takie proste.

  • Użyj zewnętrznej unikalnej wartości: możliwe, że plik cookie może być częścią kontekstu, który zapewnia wystarczającą ilość danych, aby wygenerować wartość, która będzie unikalna dla każdego szyfrowania. Na przykład, jeśli żądanie zawiera również (w przezroczystym) " identyfikator użytkownika", możesz użyć identyfikatora użytkownika jako źródła IV. Konfiguracja jest podobna do powyższej: dostajesz wszystkie te dane, wpychasz je do SHA-256, a pierwsze 16 bajtów wyjścia SHA-256 to IV, którego potrzebujesz. Działa to tylko wtedy, gdy dane te nie zmieniają się dla danej zaszyfrowanej wiadomości i jeśli są naprawdę unikalne. Jest to rzadkie zjawisko: na przykład "ID użytkownika" jest dobre tylko wtedy, gdy nigdy nie ma potrzeby ponownego szyfrowania nowej wiadomości dla tego samego użytkownika i jeśli nigdy nie ma możliwości, że identyfikator użytkownika jest ponowne użycie(np. Stary użytkownik rezygnuje, nowy przychodzi i wybiera teraz wolny identyfikator użytkownika).

Używanie losowego 16-bajtowego IV generowanego z kryptograficznie bezpiecznym PRNG jest nadal "bezpiecznym" sposobem, który polecam. Jeśli w pliku cookie znajdziesz mało miejsca, oznacza to, że zbliżasz się do limitu 4 kB, w którym to momencie możesz chcieć użyć kompresji (na danych przed szyfrowaniem; po szyfrowaniu kompresja jest bardzo mało prawdopodobna). Użyj zlib (w języku Java dostęp do zlib można uzyskać poprzez java.util.zip).

Warning: w tym wszystkim, nie mówię nic o tym, czy szyfrowanie plików cookie pomaga w zapewnieniu jakichkolwiek cech bezpieczeństwa, które próbujesz osiągnąć. Zazwyczaj, gdy potrzebne jest szyfrowanie, w rzeczywistości potrzebne jest zarówno szyfrowanie, jak i integralność, a następnie należy użyć trybu połączonego szyfrowania i integralności. Lookup GCM i CCM. Co więcej, szyfrowanie plików cookie jest głównie dobre dla jednego cel, który ma na celu uniknięcie kosztów przechowywania po stronie serwera trochę danych specyficznych dla użytkownika. Jeśli chcesz zaszyfrować plik cookie dla czegoś innego, np. aby uwierzytelnić ważnego użytkownika, robisz to źle: szyfrowanie nie jest właściwym narzędziem do tego.

 45
Author: Thomas Pornin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-12-01 12:58:03

Nie mam bezpośredniej odpowiedzi na twoje pytanie, ale kilka rzeczy do dodania.

Po pierwsze, szyfrowanie pliku cookie nie ma dla mnie sensu. Jeśli chcesz zachować poufność swoich danych, nie powinieneś ich przechowywać w pliku cookie. Jeśli chcesz integralności (tzn. nie można manipulować zawartością pliku cookie), należy użyć klucza hash (na przykład HMAC).

Kolejna uwaga to nigdy nie używać kroplówki, która jest równa 0 tylko dla wygody.

IV są równe w rozmiar z bloku. W przypadku AES-128 Rozmiar bloku wynosi 128, keysize wynosi 128, a zatem IV wynosi 128 bitów.

Najlepszym sposobem na to jest utworzenie losowego klucza AES i użycie go jako IV. ten random IV może być publiczny, o ile nie zostanie ponownie użyty w kolejnych szyfrowaniach za pomocą tego samego klucza

Edit :

Możesz zajrzeć na tę stronę wiki, aby uzyskać więcej informacji na temat trybu, którego chcesz użyć. Jednak nigdy nie używaj EBC, chyba że jesteś pewien, że powinieneś go używać. I nawet wtedy, zweryfikuj z ekspertem. Morfologia jest z tego co wiem najbezpieczniejsza (razem z PCBC).

Http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation

 4
Author: Henri,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-10-14 11:35:17

Jeśli nie zrobisz IV losowego (tzn. użyjesz jakiejś powtarzającej się grupy liczb), łatwiej będzie znaleźć klucz, jeśli plik cookie zawsze zaczyna się od tego samego wyraźnego tekstu.

Rozmiar IV dla AES-128 wynosi 128 bitów. IIRC, IV jest tej samej wielkości co blok szyfrowy. 128 bitów to 16 bajtów. 32 bajty, jeśli jest przechowywany jako ciąg szesnastkowy ASCII. Czy to naprawdę za dużo? 32 bajty w dzisiejszych czasach to niewiele...

 2
Author: Jörgen Sigvardsson,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-01-05 20:09:31

Dołącz dużą liczbę losową do pliku cookie. Liczba 64 lub 128 bitów jest prawdopodobnie wystarczająco duża. Musi być wystarczająco duży, aby uzyskanie duplikatów było bardzo trudne. Pamiętaj, aby umieścić wystarczająco dużo entropii w tej liczbie. Nie używaj tylko gettime (). Jeśli masz dostęp do CRNG, użyj go tutaj.

Przechowuj 256-bitowy klucz główny ze swoją aplikacją. Użyj SHA256, aby uzyskać kluczowe informacje. Ponownie, użyj CRNG do tego.

$keyblob = sha256( concat("aeskeyid", $masterkey , $randomnumberwithcookie ) )
$aeskey = $keyblob[0..15]
$aesiv = $keyblob[16..31]

Możesz również chcieć uzyskać klucz do HMAC.

$mackeyblob = sha256( concat("hmackeyid", $masterkey , $randomnumberwithcookie ) )

Alternatywnie, możesz połączyć powyższe dwie operacje hashowania w jedną za pomocą SHA512.

$keyblob = sha512( concat("randomkeyid", $masterkey , $randomnumberwithcookie ) )
$aeskey = $keyblob[0..15]
$aesiv = $keyblob[16..31]
$hmackey = $keyblob[32..63] 
 0
Author: Lunatic Experimentalist,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-01-06 01:23:04

Można uniknąć losowej kroplówki, używając morfologii i przechowując HMAC przed wiadomością. Użycie losowo wybranej stałej IV jest ok. Ale musisz mieć pewność, że wiadomości są różne.

Dzieje się tak, gdy zaszyfrowana wiadomość jest zawsze inna. Klucz licencyjny z numerem seryjnym spełniałby te kryteria. Plik cookie z identyfikatorem użytkownika lub identyfikatorem sesji również by do niego pasował.

Możesz użyć CBC z losową stałą IV, jeśli przechowujesz hmac przed wiadomością. Hash kumuluje wszystkie odmiany rozprzestrzenione w wiadomości w pierwszym bloku. Możesz również dodać kilka losowych bajtów lub najlepiej numer seryjny, jeśli możesz mieć pewność, że będzie unikalny lub nie zostanie ponownie użyty przez bardzo długi czas.

Nawet nie myśl o używaniu CTR ze stałą IV.

 0
Author: chmike,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-08-27 08:37:54