Mam aplikację używającą 256-bitowego szyfrowania AES, które nie jest obsługiwane przez Javę po wyjęciu z pudełka. Wiem, że aby to działało poprawnie, instaluję słoiki JCE o nieograniczonej sile w folderze bezpieczeństwa. Dla mnie jako programisty jest to w porządku, mogę je zainstalować.
Moje pytanie brzmi, ponieważ ta aplikacja będzie dystrybuowana, użytkownicy końcowi najprawdopodobniej nie będą mieli zainstalowanych tych plików zasad. Pobranie przez użytkownika końcowego tylko po to, aby aplikacja działała, nie jest atrakcyjnym rozwiązaniem.
Czy istnieje sposób, aby aplikacja działała bez nadpisywania plików na komputerze użytkownika końcowego? Oprogramowanie innej firmy, które może sobie z tym poradzić bez zainstalowanych plików zasad? Czy może sposób po prostu odwoływać się do tych plików strategii z pliku JAR?
źródło
Odpowiedzi:
Istnieje kilka często cytowanych rozwiązań tego problemu. Niestety żaden z nich nie jest w pełni zadowalający:
Ale jest też refleksja. Czy jest coś, czego nie możesz zrobić za pomocą odbicia?
Po prostu wywołaj
removeCryptographyRestrictions()
ze statycznego inicjatora lub takiego przed wykonaniem jakichkolwiek operacji kryptograficznych.Ta
JceSecurity.isRestricted = false
część jest wszystkim, czego potrzeba do bezpośredniego używania 256-bitowych szyfrów; jednak bez dwóch pozostałych operacjiCipher.getMaxAllowedKeyLength()
nadal będzie raportować 128, a 256-bitowe zestawy szyfrów TLS nie będą działać.Ten kod działa na Oracle Java 7 i 8 i automatycznie pomija proces w Javie 9 i OpenJDK, gdzie nie jest potrzebny. W końcu jest to brzydki hack, ale prawdopodobnie nie działa na maszynach wirtualnych innych dostawców.
Nie działa również na Oracle Java 6, ponieważ prywatne klasy JCE są tam zaciemnione. Obfuskacja nie zmienia się jednak z wersji na wersję, więc nadal jest technicznie możliwe wsparcie Java 6.
źródło
final
polem w 8u111 zmodyfikowałem je tak, aby mogło zmienić końcowe pole, postępując zgodnie z tą odpowiedzią . Wynik jest mniej więcej taki sam, jak w nowej wersji ntoskrnl, z tą różnicą, że nie zadeklarowałemmodifiersField
jakofinal
. Jeden z moich użytkowników zgłasza, że działa również w 8u112.Nie jest to już potrzebne w Javie 9 ani w żadnym nowym wydaniu Java 6, 7 lub 8. Wreszcie! :)
Zgodnie z JDK-8170157 nieograniczone zasady kryptograficzne są teraz domyślnie włączone.
Konkretne wersje z wydania JIRA:
Zauważ, że jeśli z jakiegoś dziwnego powodu stare zachowanie jest potrzebne w Javie 9, można je ustawić za pomocą:
źródło
Oto rozwiązanie: http://middlesphere-1.blogspot.ru/2014/06/this-code-allows-to-break-limit-if.html
źródło
java.security.InvalidKeyException: Wrong algorithm: AES or Rijndael required
isRestricted
pole stało się ostateczne ( bugs.openjdk.java.net/browse/JDK-8149417 ). Odpowiedź @ ntoskrnl uwzględnia ewentualne włączenie „końcowego” modyfikatora. Komentarz @ M.Dudley na temat umowy licencyjnej Java nadal ma zastosowanie.Bouncy Castle nadal wymaga zainstalowania słoików, o ile wiem.
Zrobiłem mały test i wydawało się, że to potwierdza:
http://www.bouncycastle.org/wiki/display/JA1/Frequently+Asked+Questions
źródło
Począwszy od JDK 8u102, opublikowane rozwiązania opierające się na refleksji nie będą już działać: polem, które te rozwiązania są ustawione, jest teraz
final
( https://bugs.openjdk.java.net/browse/JDK-8149417 ).Wygląda na to, że wrócił do (a) korzystania z Bouncy Castle lub (b) instalacji plików zasad JCE.
źródło
isRestricted
dziedzinie, ponieważ dba o ewentualne dodanie „końcowego” modyfikatora.Aby uzyskać alternatywną bibliotekę kryptograficzną, zajrzyj do Bouncy Castle . Ma AES i wiele dodatkowych funkcji. To liberalna biblioteka open source. Aby to zadziałało, będziesz musiał użyć lekkiego, zastrzeżonego interfejsu API Bouncy Castle.
źródło
Możesz użyć metody
aby przetestować dostępną długość klucza, użyj go i poinformuj użytkownika o tym, co się dzieje. Coś stwierdzającego, że aplikacja spada do 128-bitowych kluczy z powodu, na przykład, plików zasad. Użytkownicy świadomi bezpieczeństwa zainstalują pliki zasad, inni będą nadal używać słabszych kluczy.
źródło
W przypadku naszej aplikacji mieliśmy architekturę serwera klienckiego i zezwalaliśmy na odszyfrowywanie / szyfrowanie danych tylko na poziomie serwera. Dlatego pliki JCE są potrzebne tylko tam.
Mieliśmy inny problem, w którym musieliśmy zaktualizować jar bezpieczeństwa na komputerach klienckich, za pośrednictwem JNLP, nadpisuje on biblioteki w
${java.home}/lib/security/
i JVM przy pierwszym uruchomieniu.To sprawiło, że to zadziałało.
źródło
Oto zaktualizowana wersja odpowiedzi ntoskrnl . Dodatkowo zawiera funkcję do usuwania końcowego modyfikatora, takiego jak wspomniany w komentarzach Arjan .
Ta wersja działa z JRE 8u111 lub nowszym.
źródło
((Map<?, ?>) perms.get(defaultPolicy)).clear();
powoduje błąd kompilatora. Wydaje się, że komentowanie nie wpływa na jego funkcjonalność. Czy ta linia jest konieczna?Oto zmodyfikowana wersja kodu @ ntoskrnl, obejmująca
isRestrictedCryptography
sprawdzanie przez rzeczywisteCipher.getMaxAllowedKeyLength
logowanie slf4j i obsługę inicjalizacji singletona z programu ładującego aplikacji w następujący sposób:Ten kod poprawnie przestałby manipulować refleksją, gdy nieograniczone zasady staną się domyślnie dostępne w Javie 8u162, jak przewiduje odpowiedź @ cranphin.
źródło
Podczas instalacji programu wystarczy zachęcić użytkownika i pobrać skrypt DOS Batch lub skrypt powłoki Bash i skopiować JCE do odpowiedniej lokalizacji systemowej.
Kiedyś musiałem to robić dla usługi sieciowej serwera i zamiast formalnego instalatora dostarczyłem po prostu skrypty do konfiguracji aplikacji, zanim użytkownik będzie mógł ją uruchomić. Możesz uniemożliwić uruchamianie aplikacji, dopóki nie uruchomią skryptu instalacyjnego. Możesz również sprawić, by aplikacja narzekała, że brakuje JCE, a następnie poprosić o pobranie i ponowne uruchomienie aplikacji?
źródło