Jaki jest najlepszy sposób ochrony poufnych danych w kodzie?

Badałem sposoby ochrony mojego kodu przed dekompilacją.

Jest tu kilka dobrych wątków opisujących zaciemnianie i pakowanie kodu jako możliwe sposoby ochrony kodu. Jednak żadna z nich nie jest idealna, zaciemnienie nie działa z odbiciem, gdy używane są nazwy metod/właściwości łańcuchowych. Wiele osób w ogóle nie zaleca stosowania zaciemniania.

Więc obecnie postanowiłem nie iść z żadnym z powyższych. jednak, mam części kodu tam, gdzie potrzebuję pewnego rodzaju szyfrowania, na przykład ciąg połączenia z bazą danych z adresem IP, loginem i hasłem jest przechowywany w kodzie jako prosty const string, taki sam jak dane konta e-mail.

W ASP.NET istnieje opcja przeniesienia poufnych danych do pliku .config i zaszyfrowania go, ale wymaga to klucza serwera, tzn. połączonego z jednym komputerem. Nie czytałem o tym zbyt wiele, ale przypuszczam, że coś podobnego jest dostępne dla aplikacji desktopowych. Ale potrzebuję tego do pracy na dowolnym komputer, na którym zainstalowana jest aplikacja.

I tu pojawia się pytanie: Czy istnieją sposoby kodowania/ochrony takich danych, aby nie mogły być odczytywane wraz z dekompilowanym kodem?

Author: M.Babcock, 2011-10-21

7 answers

Pierwsza rada to Nigdy nie przechowywać niczego wrażliwego bezpośrednio w kodzie. Możesz Zawsze odtworzyć to, bez względu na to, jak sprytnie próbujesz to zaciemnić.

Czytałem o takich rzeczach jak łamanie hasła na kilka kawałków, umieszczanie ich w różnych miejscach kodu i uruchamianie ich przez szereg funkcji, zanim w końcu ich użyłem... chociaż utrudnia to działanie, nadal można monitorować aplikację za pomocą debuggera i ostatecznie będziesz w stanie odzyskać tajne informacje.

Jeśli dobrze zinterpretuję twój scenariusz, to masz kod, który ma być wdrożony w lokalu jakiegoś klienta i twój kod jest podłączony do bazy danych (która przypuszczam, że jest również pod nadzorem klienta), podłączenie do niej wymaga hasła. To hasło jest znane temu klientowi, więc próba ukrycia go przed Klientem jest raczej bezużyteczna. To, czego chcesz, to ograniczyć dostęp do tego hasła każdemu, kto nie jest powinienem to wiedzieć.

Zazwyczaj osiąga się to poprzez umieszczenie poufnych informacji w osobnym pliku w folderze, który powinien mieć bardzo restrykcyjne uprawnienia, tylko aplikacja i garstka wybranych osób powinna mieć dostęp. Aplikacja będzie wtedy uzyskiwać dostęp do informacji w razie potrzeby podczas wykonywania.

DODATKOWO szyfrowanie oddzielnego pliku okazuje się być problemem - jeśli tak się stanie, to jest klucz, który ponownie musi być jakoś zabezpieczony - nieskończona rekurencja jest na dobrej drodze:) zabezpieczenie dostępu do pliku jest często wystarczające, ale jeśli naprawdę chcesz być jak najbardziej bezpieczny, rozwiązaniem jest użycie szyfrowania opartego na hasłach dla pliku. Chodzi jednak o to, aby nie przechowywać hasła w innej lokalizacji w systemie, ale raczej jako informacje poza pasmem (np. w fizycznym skarbcu) i wprowadzić hasło podczas uruchamiania aplikacji. To również ma swoje problemy: fizyczna obecność osoby jest wymagana dla (ponowne)uruchomienie aplikacji i nadal można odzyskać hasło z pamięci RAM komputera, na którym aplikacja jest uruchomiona. Ale to chyba najlepsze, co możesz zrobić bez specjalistycznego sprzętu.

Inną dobrą alternatywą dla szyfrowania opartego na hasłach byłoby poleganie na specyficznych dla systemu operacyjnego "skarbcach haseł", takich jak izolowana Pamięć masowa systemu Windows , jest to rodzaj kompromisu między nieszyfrowaniem w ogóle i utrzymaniem hasła poza pasmem.

 15
Author: emboss,
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-11-16 10:40:22

Nie jest to odpowiedź szyfrująca, ale jednym ze sposobów na "zabezpieczenie" byłoby wykonywanie wszystkich połączeń z bazą danych za pośrednictwem usługi internetowej. Twoje poświadczenia połączenia będą następnie przechowywane na bezpiecznym serwerze, a klienci przechodzą tam wszystkie połączenia.

Nic wrażliwego nie jest przechowywane w Twoim re-distributable w ogóle...

 11
Author: Paddy,
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-10-21 13:02:22

Zmagałem się z tym problemem w przeszłości i wymyśliłem trzy sposoby radzenia sobie z tym problemem, ale nie jestem pewien, czy któryś z nich jest idealny:

  1. zaciemniać lub szyfrować wartość i mieć nadzieję na najlepsze. Szyfrowanie jest oczywiście dodatkowym poziomem zaciemnienia, ponieważ klucz musi być dostarczony wraz z resztą.
  2. wyeliminuj potrzebę użycia samego klucza, używając szyfrowania jednokierunkowego. Użyj klucza prywatnego do wygenerowania klucza publicznego. Można go wykorzystać do licencjonowania lub Walidacja hasła. Licencje generowane są za pomocą klucza prywatnego, ale klucz publiczny może być użyty do ich walidacji. Możesz też użyć klucza prywatnego do wygenerowania hasła, które można zweryfikować, ale nie odwrócić za pomocą klucza publicznego.
  3. Stwórz własny systemowy mechanizm generowania kluczy podobny do tego używanego przez ASP.NET. możesz ograniczyć efekt cofania szyfrowania / zaciemniania w kroku 1, generując unikalny klucz dla każdej instalacji lub witryny.
 5
Author: BlueMonkMN,
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-10-21 13:05:46

Istnieje mnóstwo metod, ale rzeczywistość jest taka, że jeśli naprawdę chcesz chronić swój kod, jedynym rozwiązaniem jest użycie "profesjonalnych" produktów : -) nie próbuj odkrywać koła na nowo. Te produkty zwykle mają opcje szyfrowania ciągów. Prawdziwy problem jest inny: bez produktu profesjonalnego (a nawet z produktem profesjonalnym) ekspert może po prostu umieścić punkt przerwania i spojrzeć na parametry przekazywane do metody bibliotecznej (na przykład tej, która otwiera połączenia). Teraz... Jeśli naprawdę chcesz zaszyfrować ciągi kodu, jest to dość proste. Ale czy to by się przydało? Nie.

Teraz, aby nikt nie oznaczał tego jako "nie ODPOWIEDŹ", wrzucę jakiś prosty kod szyfrujący/deszyfrujący:

// Generate key. You do it once and save the key in the code
var encryptorForGenerateKey = Aes.Create();
encryptorForGenerateKey.BlockSize = 128;
encryptorForGenerateKey.KeySize = 128;
encryptorForGenerateKey.GenerateKey();
encryptorForGenerateKey.GenerateIV();

var key = encryptorForGenerateKey.Key;
var iv = encryptorForGenerateKey.IV;

// Encrypt: this code doesn't need to be in the program. You create a console
// program to do it
var encryptor = Aes.Create();
var encryptorTransformer = encryptorForGenerateKey.CreateEncryptor(key, iv);

string str = "Hello world";
var bytes = Encoding.UTF8.GetBytes(str);
var encrypted = encryptorTransformer.TransformFinalBlock(bytes, 0, bytes.Length);
var encryptedString = Convert.ToBase64String(encrypted);

Console.WriteLine(encryptedString);

// Decrypt: this code needs to be in the program

var decryptor = Aes.Create();
var decryptorTransformer = decryptor.CreateDecryptor(key, iv);

byte[] encrypted2 = Convert.FromBase64String(encryptedString)

var result = decryptorTransformer.TransformFinalBlock(encrypted2, 0, encrypted2.Length);

var str2 = Encoding.UTF8.GetString(result);

Ten kod najwyraźniej nie jest bezpieczny. Każdy może dekompilować program, dodać Console.WriteLine(str2) i przekompilować go.

 4
Author: xanatos,
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-10-21 12:58:31

Możesz oczywiście zaszyfrować swój ciąg przed kompilacją, ale twój kod potrzebuje tego w zwykłym tekście, jeśli używasz prostego adresu db lub http.

W tym przypadku nie ma prawdziwej ochrony: każdy może słuchać (breakpoint) określonej metody i po wywołaniu zobaczyć, co się dzieje bez czytania kodu. Więc nie, nie ma prawdziwej ochrony przed tym, również za pomocą zaciemniania w pewnym momencie wywołasz jakąś metodę. NET z tym ciągiem tekstowym, a wszyscy mogę to przeczytać.

Można na przykład umieścić COM lub C++ dll do przechowywania zaszyfrowanych ciągów. Niezarządzana biblioteka dll nie jest dekompilowalna, jednak eksperci mogą oczywiście zrozumieć demontaż biblioteki dll. I jak wspomniano wcześniej, kiedyś będziesz potrzebował zwykłych danych, a w tym momencie nie ma ochrony, która może trwać.

Jedyne, co możesz zrobić, to zmienić swoją architekturę.

Na przykład, jeśli twój db jest online, a Twoja aplikacja jest aplikacją kliencką, możesz połącz się za pomocą usług internetowych. Wtedy możesz ujawnić tylko usługi sieciowe, których użytkownik naprawdę potrzebuje, nie ma ryzyka pisania zapytań sql przez użytkownika. Następnie możesz dodać logikę ochrony na serwerze zamiast na kliencie.

Jeśli wszystko jest w trybie offline, niewiele możesz zrobić, możesz utrudnić życie za pomocą prostego szyfrowania ciągów, ale nigdy nie będzie to prawdziwa ochrona.

 3
Author: Salvatore Previti,
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-10-21 13:46:47

Jak zauważył Lucas w swoim komentarzu, jeśli masz tylko jeden kawałek, to każdy dekompilujący Twoją aplikację może go odtworzyć i odszyfrować hasła do bazy danych.

Jeśli chodzi o przechowywanie danych uwierzytelniających, moją zwyczajową praktyką jest zawsze przechowywanie ich w pliku konfiguracyjnym aplikacji. Jeśli muszę to zabezpieczyć, używam SecureString i jakiegoś szyfrowania. I to może działać dla każdego rodzaju informacji konfiguracyjnych, nie tylko poświadczeń. Jest naprawdę dobry artykuł o zabezpieczeniu pliki konfiguracyjne tutaj: szyfrowanie haseł w aplikacji. NET.plik konfiguracyjny

 3
Author: Ucodia,
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-10-21 14:16:47

Może powinieneś przeczytać więcej na temat szyfrowania sieci.config http://learn.iis.net/page.aspx/141/using-encryption-to-protect-passwords/

W Przeciwnym Razie nie ma wiele można zrobić. Przechowywanie poufnych danych w kodzie nie jest opcją, ponieważ każdy z narzędziem reflektor może je otworzyć i zobaczyć. Jeśli chcesz, aby Kod lub zmienne były niewidoczne dla wszystkich, powinieneś utworzyć webservice na prywatnym serwerze, który akceptuje dane, przekształca je za pomocą it ' s magic i zwraca je klientowi. W ten sposób wszystko pomiędzy publikowaniem a pobieraniem danych jest utrzymywane w tajemnicy.

 1
Author: Erwin,
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-10-21 13:00:18