Gdzie przechowywać klucz prywatny?

22

Powiedz, że chcę, aby niektóre części mojego oprogramowania były szyfrowane. Na przykład poświadczenia dla bazy danych itp. Muszę gdzieś przechowywać te wartości, ale zrobienie tego w postaci czystego tekstu ułatwiłoby atakującemu uzyskanie nieautoryzowanego dostępu.

Jeśli jednak zaszyfruję jakiś czysty tekst, to gdzie mam przechowywać klucz? Wszystko, do czego ma dostęp oprogramowanie, zdecydowany atakujący miałby do niego dostęp, bez względu na poziom zaciemnienia:

  • Powiedzmy, że klucz jest chroniony przez model bezpieczeństwa systemu plików; ale co z (złośliwymi) superużytkownikami lub platformami, które nie zapewniają takiej wierności?
  • Lub klucz jest zapisany na stałe w plikach binarnych oprogramowania, ale zawsze można go było zdekompilować, a co z oprogramowaniem open source lub interpretowanym kodem?
  • Jeśli klucz zostanie wygenerowany, taki algorytm musiałby być deterministyczny (przypuszczalnie), a następnie ten sam problem dotyczy ziarna.
  • itp.

Kryptografia jest tak silna jak najsłabsze ogniwo w swoim łańcuchu i wydaje się to dość luźne! Zakładając, że jest to właściwe narzędzie do pracy (humor mnie), to w jaki sposób można bezpiecznie zabezpieczyć takie informacje?


Jeśli chodzi o odpowiednie narzędzie do zadania: Prawdopodobnie, na przykład w przypadku dostępu do usługi (bazy danych, serwery uwierzytelniające itp.), Ograniczysz dostęp na tym poziomie za pomocą konta usługi, może z pewnym poziomem usług audyt itp., więc posiadanie poświadczeń w postaci czystego tekstu nie stanowi problemu.

Wydaje mi się jednak, że nadal nie jest to odpowiednie: nie chcę, żeby ktoś grzebał tam, gdzie nie powinien!

Xophmeister
źródło
6
Interesujące mogą być różne posty w Security.SE . Zauważę, że niektóre frameworki i języki zapewniają specjalistyczne wsparcie dla tego (np. Zaszyfrowane sekcje konfiguracji w .net).
Brian,
9
niestety niewiele można zrobić przeciwko „złośliwym administratorom”. Ponieważ twoje oprogramowanie potrzebuje dostępu do kluczy, tak samo będzie z każdym superużytkownikiem, ponieważ będą oni mogli zmieniać / ominąć prawie każdą ACL, którą możesz wprowadzić.
DXM,
16
Jedynym absolutnie bezpiecznym sposobem na uniknięcie konieczności ufania użytkownikowi w tajemnicę jest uniknięcie potrzeby takiego sekretu. Typowym rozwiązaniem jest uruchamianie oprogramowania na serwerze pod Twoją kontrolą i rozpowszechnianie tylko niezabezpieczonego interfejsu, za pomocą którego użytkownik może uwierzytelnić się na serwerze, a następnie korzystać z usług z serwera.
amon
2
Odpowiedź Amona nie ogranicza się do użytkownika, ale dowolnego klienta. DXM podnosi również kwestię, że nie możesz chronić swojego systemu przed kimś, kto chce nim manipulować i nie powinieneś zużywać energii, aby utrudnić mu to. Zamiast tego zużywaj energię na produkt, aby nie byli zainteresowani
Kevin,
3
W przypadku złośliwych klientów najlepsze, co możesz zrobić, to ograniczyć ich do dobrze zdefiniowanego interfejsu API usługi, nie dając im bezpośredniego dostępu do bazy danych. Naprawdę nie możesz zrobić nic poza tym, ponieważ nie możesz ukryć sekretu w kliencie.
CodesInChaos,

Odpowiedzi:

25

Przede wszystkim nie nazwałbym siebie ekspertem bezpieczeństwa, ale byłem w stanie odpowiedzieć na to pytanie. To, co odkryłem, nieco mnie zaskoczyło: nie ma czegoś takiego jak całkowicie bezpieczny system . Myślę, że całkowicie bezpieczny system to taki, w którym wszystkie serwery są wyłączone :)

Ktoś pracujący ze mną w tym czasie opisał projektowanie bezpiecznego systemu pod względem podnoszenia poprzeczki dla intruzów. Tak więc każda warstwa zabezpieczenia zmniejsza szansę na atak.

Na przykład, nawet jeśli możesz doskonale zabezpieczyć klucz prywatny, system nie jest całkowicie bezpieczny. Ale prawidłowe stosowanie algorytmów bezpieczeństwa i aktualizowanie poprawek podnosi poprzeczkę. Ale tak, superkomputer wystarczająco mocny i mający wystarczająco dużo czasu może przerwać szyfrowanie. Jestem pewien, że wszystko to jest zrozumiałe, więc odzyskam pytanie.

Pytanie jest jasne, więc najpierw spróbuję zająć się każdym z twoich punktów:

Powiedzmy, że klucz jest chroniony przez model bezpieczeństwa systemu plików; ale co z (złośliwymi) superużytkownikami lub platformami, które nie zapewniają takiej wierności?

Tak, jeśli używasz czegoś takiego jak Windows Key Store lub klucz prywatny TLS zaszyfrowany hasłem, jesteś narażony na użytkowników, którzy mają hasło (lub dostęp) do kluczy prywatnych. Ale myślę, że zgodzisz się, że podnosi poprzeczkę. Listy ACL systemu plików (jeśli są poprawnie zaimplementowane) zapewniają całkiem dobry poziom ochrony. Jesteś w stanie osobiście zweryfikować i poznać swoich superużytkowników.

Lub klucz jest zapisany na stałe w plikach binarnych oprogramowania, ale zawsze można go było zdekompilować, a co z oprogramowaniem open source lub interpretowanym kodem?

Tak, widziałem na stałe klucze w plikach binarnych. Ponownie podnosi to nieco poprzeczkę. Ktoś atakujący ten system (jeśli jest to Java) musi zrozumieć, że Java wytwarza kod bajtowy (itp.) I musi wiedzieć, jak go zdekompilować. Jeśli używasz języka, który zapisuje bezpośrednio w kodzie maszynowym, możesz zauważyć, że podnosi to poprzeczkę nieco wyżej. Nie jest to idealne rozwiązanie bezpieczeństwa, ale może zapewnić pewien poziom ochrony.

Jeśli klucz zostanie wygenerowany, taki algorytm musiałby być deterministyczny (przypuszczalnie), a następnie ten sam problem dotyczy ziarna.

Tak, zasadniczo algorytm staje się informacją klucza prywatnego do utworzenia klucza prywatnego. Musiałby więc być chroniony.

Myślę więc, że zidentyfikowałeś podstawowy problem z jakąkolwiek polityką bezpieczeństwa, zarządzaniem kluczami . Posiadanie zasad zarządzania kluczami jest kluczowe dla zapewnienia bezpiecznego systemu. I jest to dość szeroki temat .

Pytanie brzmi, jak bezpieczny musi być Twój system (a zatem klucz prywatny)? Jak wysoko w twoim systemie trzeba podnieść poprzeczkę?

Teraz, jeśli chcesz zapłacić, są ludzie, którzy opracowują rozwiązania tego problemu. Skończyło się na użyciu HSM (Hardware Security Module) . Jest to zasadniczo serwer odporny na manipulacje, który zawiera klucz sprzętowy. Tego klucza można następnie użyć do utworzenia innych kluczy używanych do szyfrowania. Chodzi o to, że (jeśli jest poprawnie skonfigurowany), klucz nigdy nie opuszcza HSM. HSM dużo kosztują . Ale w niektórych firmach (powiedzmy, ochrona danych kart kredytowych) koszt naruszenia jest znacznie wyższy. Więc jest równowaga.

Wiele HSM korzysta z kart kluczowych od konserwacji i administrowania funkcjami. Kworum kart kluczowych (powiedzmy 5 z 9) musi zostać fizycznie umieszczone na serwerze w celu zmiany klucza. To podnosi poprzeczkę całkiem wysoko, pozwalając na naruszenie tylko w przypadku zmowy kworum superużytkowników.

Mogą istnieć rozwiązania programowe, które zapewniają podobne funkcje do HSM, ale nie wiem, czym one są.

Wiem, że to tylko sposób na odpowiedź na pytanie, ale mam nadzieję, że to pomoże.

Davin Tryon
źródło
2
„Wydaje mi się, że całkowicie bezpieczny system to taki, w którym wszystkie serwery są wyłączone” i nie ma sposobu, aby je włączyć.
StingyJack
2

Tego, czego chcesz, nie da się zrobić.

Powiedzmy, że klucz jest chroniony przez model bezpieczeństwa systemu plików; ale co z (złośliwymi) superużytkownikami lub platformami, które nie zapewniają takiej wierności?

Zasadniczo chcesz ochrony przed złośliwymi ludźmi. W twoim modelu w pewnym momencie ktoś będzie miał dostęp do klucza. Co jeśli ta osoba jest złośliwa? Co jeśli jesteś złośliwy? Widzisz, problem jak twierdzisz jest nierozwiązywalny, z wyjątkiem braku klucza.

Więc nie pracuj z poświadczeniami bazy danych, ale innymi mechanizmami uwierzytelniania. Ale nie ważne co, ktoś w pewnym momencie potrzebuje dostępu do danych i że ktoś może być złośliwy.

Pieter B.
źródło
2

Jest to jeden z tych problemów, których tak naprawdę nie można rozwiązać na tym samym poziomie, w jakim został stworzony. Będziemy musieli cofnąć się do kilku podstawowych filozofii i podążać kaskadą w nadziei na rozwiązanie.

Pierwszą filozofią jest „nigdy nie ufaj klientowi”, a ściśle związane „jeśli naprawdę chcesz zachować tajemnicę, nie mów nikomu!”

Prostym przykładem są poświadczenia bazy danych, jak wspomniałeś. Oczywiście chcesz, aby Twój klient miał do niego dostęp, ale nie losowy nieznajomy Internet, więc potrzebujesz jakiegoś systemu identyfikacji / weryfikacji / logowania. Ale podstawową przesłanką ukrywania tego jest problem: jeśli sam użytkownik musi posiadać sekret, ale nie chcesz, aby wiedział, co to jest sekret, wszystko, co możesz zrobić, to ukryć go lub utrudnić mu otwarcie ” tajny pakiet ". Ale nadal mogą się dowiedzieć, więc lepiej mieć plan tworzenia kopii zapasowych!

Najłatwiejszym rozwiązaniem jest „nie rób tego”. Użyj poświadczeń konta użytkownika, aby zezwolić na dostęp klienta do bazy danych oprogramowania i to wszystko. Jeśli klient stanie się złośliwy, najgorszym scenariuszem powinno być zepsucie własnych danych. to jest to! Twoja baza danych i system powinny co najwyżej zawierać niepotrzebne wpisy od tego klienta, wyłącznie dla tego klienta, a nikt inny (w tym ty) nie cierpi z powodu chaosu.

Istnieją konkretne przypadki użycia, w których po prostu chcesz, aby wdrażane oprogramowanie coś robiło, ale nie wszyscy na świecie mogli się łączyć i robić to samo, ale w tym celu po prostu ukrywasz sekrety, a jedynym dobrym powodem jest po prostu zmniejszyć bóle głowy lub aktywność systemu. Jeśli twoje ukryte informacje stają się powszechną wiedzą, lepiej nie łamać gry, w najgorszym razie denerwujące.

Jeśli jesteś w jednym z tych wąskich przypadków użycia, chodzi tylko o zaciemnienie, które polega na kreatywności. To naprawdę przypomina Code Golfa - tyle że to ty tworzysz puzzle. To wszystko, czym tak naprawdę jest - układanka. A ludzie lubią rozwiązywać łamigłówki, więc znowu lepiej będzie, gdy ktoś to rozwiąże.

Ale w większości rzeczy na świecie najlepiej jest działać, nie martwiąc się o konieczność zachowania tajemnicy przed użytkownikiem. Zamiast tego najlepszą praktyką jest po prostu pozwolić użytkownikowi na ujawnienie tajnego klucza, nałożenie na niego odpowiedzialności za pomoc w jego ochronie (na przykład jego nazwę użytkownika i hasło) oraz ograniczenie ryzyka pogorszenia tego, co się stanie, jeśli sekret zostanie ujawniony lub zostanie wykorzystany.

W prawdziwych kontekstach kryptograficznych / bezpieczeństwa „zarządzania kluczami” odpowiedź „gdzie przechowywać klucz prywatny” brzmi „gdzie indziej!” Szyfrowanie to ochrona punkt-punkt, a szyfrowanie kluczem publiczno-prywatnym ma na celu ochronę informacji przesyłanych w czasie i przestrzeni. Klucz prywatny jest z natury podatny na ataki, a jego ochrona nie jest tak naprawdę kwestią nakładającego się szyfrowania - zabezpiecza go całkowicie przed dostępem. A jeśli system musi uzyskać do niego dostęp, to sam system musi być zabezpieczony - i nie można tego zrobić na komputerze klienta. Zawsze mogą uruchomić maszynę wirtualną, zrzucić pamięć RAM, wąchać ruch sieciowy, zainstalować serwer proxy lub wirtualną kartę sieciową, dekompilować pliki wykonywalne ... nie angażuj się dobrowolnie w tę przegraną bitwę.

Teraz, jeśli musisz zrobić coś takiego jak DRM, gdzie potrzeba przechowywania tajemnicy jest w rzeczywistości oparta na kontrolowaniu korzystania z samego oprogramowania, to zupełnie inna sytuacja .


TLDR: Nie zachowuj tajemnic przed użytkownikiem, zachowuj tajemnice przed użytkownikiem.

BrianH
źródło
1

Jeden z obecnie używanych systemów działa w ten sposób.

  • Zaczynam od formularza logowania do usługi uwierzytelniania. Wykorzystuje uwierzytelnianie dwuskładnikowe, aby upewnić się, że jestem tym, za kogo się podaje.
  • Otrzymuję tymczasowy certyfikat SSL, którego mogę użyć do uzyskania dostępu do chronionej usługi. Usługa śledzi akceptowane przez siebie certyfikaty.
  • Moje wymiany danych są szyfrowane przez ten certyfikat przed podsłuchem. Próba złamania go nie jest zbyt przydatna, ponieważ wygasa.
  • Certyfikat wygasa szybko (za kilka godzin), ale nie za szybko, więc nie muszę podawać hasła dla każdej interakcji.
  • Certyfikat można natychmiast cofnąć po drugiej stronie.

Oczywiście usługa chroniona działa gdzieś poza moim zasięgiem. Może działać na moim komputerze pod innym kontem (i ewentualnie w kontenerze), ale mam uprawnienia administratora i mogę wtedy próbować ominąć ograniczenia.

Zasadniczo, jeśli masz złośliwego administratora, wszystkie zakłady są wyłączone. I powinieneś założyć obecność złośliwego superużytkownika w swoim modelu zagrożenia.

Musisz więc odizolować chronioną usługę od komputera dostępnego dla klienta. Przenieś chronioną usługę na maszynę dostępną tylko przez sieć. Umieść swoich klientów na maszynach wirtualnych, które uniemożliwiają im dotarcie do reszty komputera fizycznego, na którym działa usługa chroniona.

Jeśli twoja chroniona usługa nie jest tak cenna, aby móc zarządzać takimi środkami, skorzystaj z dowolnego magazynu zaszyfrowanych kluczy, jaki daje ci system operacyjny: zarówno Windows, Linux, jak i OSX mają implementacje keyring.

9000
źródło
-1

Moim zdaniem jedynym sposobem na zapewnienie tego bezpieczeństwa jest szyfrowanie klucza / hasła za pomocą hasła do odblokowania. W ten sposób hasło należy podać przy każdym rozpoczęciu lub użyciu tajemnicy. Niezbyt przydatne.

Innym sposobem może być posiadanie systemu bezpieczeństwa przez samo konto bazy danych. Niezbyt skalowalny ...

Jeśli każdy użytkownik w systemie ma swoje własne konto DB, a konta te zostały wstępnie skonfigurowane, więc aplikacja nie ma uprawnień do tworzenia kont w DB w imieniu użytkownika, można jednak podejść dość blisko. Nie jest to również dobre rozwiązanie, więc sądzę, że musisz mieć bardzo ograniczony dostęp do odczytu plików konfiguracyjnych i zaufać swoim superużytkownikom.

polve
źródło