Piszę serwer aplikacji i zdecydowałem się użyć AES128/CTR/NoPadding do zabezpieczenia połączeń, ponieważ jest uważany za wystarczająco bezpieczny bez konieczności rozszerzania bajtów do bloku Granica i pomyślałem, że jest to dobre dopasowanie do TCP, który logicznie jest płynnym strumieniem.Symulacja szyfru strumieniowego z AES/CTR
Problem polega na tym, że Cipher.update() nie zwraca zaszyfrowanego bloku, dopóki nie ma pełnego 16-bajtowego bloku, ponieważ CTR jest zasadniczo oparty na szyfrowaniu blokowym, chociaż symuluje szyfr strumienia. Powinienem czytać dane z gniazda TCP i przetwarzać komunikaty zaraz po ich dostarczeniu, ale nie mogę pobrać najnowszego bloku, ponieważ wciąż się buduje, a jego rozmiar jest mniejszy niż 16 bajtów. I nie mogę po prostu czekać, ponieważ nie wiemy, kiedy zostanie wysłana następna wiadomość. Oczywiście mógłbym wywołać Cipher.doFinal(), aby uzyskać resztki, ale to oznaczałoby koniec strumienia (połączenia) i obiekt Cipher zostałby ponownie zainicjowany.
Pomyślałem, że byłoby miło, gdyby można było zajrzeć do przeniesienia. CTR po prostu XORs zwykły tekst ze strumieniem klucza, więc powinienem być w stanie uzyskać zaszyfrowane dane bez względu na resztę bajtów w bloku. Czy byłby to dobry sposób obejścia tego problemu? Zastanawiam się nad napisaniem owijki, która szyfruje fałszywy zwykły tekst z zerami, aby uzyskać strumień kluczy z wyprzedzeniem i XOR ręcznie, ale zastanawiam się, jak inni rozwiązali ten problem.
Aktualizacja
Zajmuję się tworzeniem aplikacji na Androida i okazało się, że jest to problem Dalvik VM. Jak zauważyli Robert i Monnand poniżej, Java SE nie ma tego problemu przynajmniej z domyślnym dostawcą. Myślę, że będę musiał napisać klasę opakowania lub zmienić tryb na CFB8, aby obejść ten problem. (CTR8 nie zadziałało) Dzięki za wszystkie odpowiedzi!
Czy można podkładać wiadomości tak, aby ich długość była wielokrotnością liczby 16? Zapewni to, że zawsze otrzymasz odszyfrowany fragment. –
@Chris: Dzięki za sugestię, to może być możliwe obejście problemu. Ale chciałbym tego uniknąć, jeśli to możliwe, ponieważ nie jest to lepsze z punktu widzenia wydajności sieci, chociaż może być pomijalne. –
Możesz po prostu wywołać to na tablicy składającej się z zer, aby uzyskać strumień klucza. Następnie lub ręcznie lub do wiadomości. – CodesInChaos