Hasło do bazy w kodzie programu

0

Witam,

  1. Piszę program który łączy się z bazą danych, w kodzie źródłowym przetrzymuje hasło do bazy. Jedna boje się że jeżeli użyjemy programu do dassemblowania np. ILDasm to uda nam się wyciągnąć to hasło. Wymyśliłem że napiszę algorytm szyfrowania i będę przetrzymywał zaszyfrowane dane, a program je sobie odszyfruje, co o tym sądzicie ? Może są lepsze sposoby ?

  2. Program ma również dołączony plik .pfx (certyfikat do szyfrowania połączenia SSL). W jaki sposób wsadzić go w plik .exe ?

Pozdro.

0

Cokolwiek byś nie zrobił, jeśli hasło jest w programie można je będzie odzyskać, albo przez deasemblera, albo przez debuggera (np. dodatek Deblector dla .NET Reflectora) albo przez programy monitorujące połączenia sieciowe do bazy danych ;), dodatkowe szyfrowanie może co jedynie spowolnić uzyskanie tych informacji.

Dowolny plik binarny możesz osadzić jako zasób w projekcie C#.

byte[] myFile = global::nazwa_projektu.Properties.Resources.nazwa_zasobu_binarnego;

0

Wydaje mi się że przez program monitorujący ruch sieciowy się nie da z tego względu że jest to szyfrowane SSL. W taki razie w jaki sposób przechowywać takie poufne dane ?

0

Można by się pokusić o ataki man-in-the-middle, poza tym mając dostęp do aplikacji można przechwycić dowolne dane, która ona przetwarza (zanim jeszcze nastąpi szyfrowanie).

Takich danych NIE MOŻNA przechowywać, to z założenia jest błąd, należy zmienić sposób funkcjonowania oprogramowania, przykro mi bardzo, wszelkie metody na "chowanie" haseł w aplikacjach to tylko półśrodki, dzięki którym naiwni programiści myślą, że mogą spać bezpiecznie podczas, gdy naprawdę narażają tak ehem "chronione" dane na kradzież / modyfikację.

1

Nie jest to dokladnie to o co pytasz, ale w kontekscie "chowania" popelnilem ostatnio przydlugawy post -> UserControl ale nie w dll, w ktorym najwazniejszym wnioskiem jest to, co napisal Bartosz, "że idealnie się nie da", ale wbrew temu czym Bartosz (i ja:) ) Cie straszymy, "im wiecej wepchniesz zabezpieczen, tym wiecej ludzi to potrafiacych odsiejesz". Jesli wiec nie jest to cos za co bedziesz reczyl glowa, finansami albo zyciem swoim lub innych, nie musisz tego robic ultra-securo-idealnie.

..acz wypadaloby zeby nie bylo latwiej wyciagnac tego hasla z programu niz zlamac SSL'a.. atakuje sie zawsze najslabsze ogniwo, wiec skoro potrebujesz SSL, to niestety, o ochronie kodu i tego co w nim siedzi, lub siedziec nie moze, czas zaczac myslec.. nie jest to latwe i gotowego rozwiazania mozesz nie dostac. zeby takie znalezc, trzeba znac zwykle cala sytuacje i kontekst "aktorow" stojacych na poszczegolnych stronach komunikacji, a nie tylko ze "chcesz schowac haslo"

w kontekscie laczenia sie ze zdalna baza danych, najlepiej, zeby to uzytkownik musial te hasla znac i podawac.. ale to pewnie nie jest mozliwe?:)

0

Hasło możesz trzymać w pliku konfiguracyjnym (w aplikacji forma app.config), który możesz częściowo (tylko connection string) lub w całości zaszyfrować. W standardowy sposób pobierając dane z config'a nie przejmujesz się odszyfrowywaniem, bo robi to .net, dla ciebie jest to przezroczyste.
http://msdn.microsoft.com/en-us/library/ff647398.aspx

0

Niestety hasło musi być w programie z tego względu, że użytkownik nie może go znać. Domyślam się że rozwiązania idealnego nie ma (są ludzie którzy łamią nawet zabezpieczenia bankowe...). Jednak chodzi o utrudniony dostęp do tych danych. Chyba zastanowię się nad tym szyfrowanym configiem, może da się go w exe wkomponować ? Dostęp będzie jeszcze bardziej utrudniony.

0

Podaj po wszystkim nazwe programu to znajde Ci to hasło i je upublicznie, żeby Ci pokazać jak bardzo się mylisz i jeszcze innym zalecasz takie badziewne rozwiazania.

0
swat09 napisał(a)

Niestety hasło musi być w programie z tego względu, że użytkownik nie może go znać. Domyślam się że rozwiązania idealnego nie ma (są ludzie którzy łamią nawet zabezpieczenia bankowe...). Jednak chodzi o utrudniony dostęp do tych danych. Chyba zastanowię się nad tym szyfrowanym configiem, może da się go w exe wkomponować ? Dostęp będzie jeszcze bardziej utrudniony.

o, istotna informacja. czyli uzytkownicy nie sa na tyle zaufani, aby znac haslo do bazy ktorej beda uzywac? hm..
to jeszcze trzy wazne pytanie:

  • czy w ogole fakt istnienia tej bazy jest jawny?
  • dlaczego obawiasz się że użytkownik znający haslo do tej bazy, może jej zaszkodzić? [pamietaj, ze na bazie można ustawiac uprawnienia nawet z rozroznieniem na operacje insert/delete/itp!]
  • na ile bezpieczny musi byc Twoj "system"? porownaj to do czegos "znanego". projekt na zaliczenie i profer sie czepia? e-zakupy? e-ankiety? portal i rejestracja uzytkownikow? firma i listy pracownikow? firma i system fakturujacy? szpital i informacje o lekach? teatr/kino i rezerwacje miejsc? wojsko i plany ewakuacji miasta?

a teraz, czesciowo dowcip, czesciowo odpowiedz:
Jesli stopien ochrony ma byc jakis, ale nie musi byc wysoki ani nawet sredni, byle by "szczawikow" i "script kiddies" odstreczyc, wymysl haslo bedace nieoczywistym ale dobrze znanym przez wszystkich napisem.. na przyklad, jeśli Twoj connstring, bez hasla, ma ogolnie postac:
Data Source=myServerAddress;Initial Catalog=myDataBase;User Id=myUsername
to nie uzywaj app.config, tylko wyryj to gdzies w programie, w kawałkach, potem gdzies w programie to posklejaj, przekaz gdzie indziej, niech to gdzie-indziej dolepi Password równe temu pozlepianemu napisowi (tak, password=connectionstringbezhasla), przekaz to jeszcze gdzies indziej, i dopiero stamtad uzywaj. potem po skonczeniu programu przelec wszystko dotsfucatorem

plusy:

  • jawnie stringiem w binarce connstring sie nie pojawi
  • jak ktos znajdzie gdzie budujesz connstringa, co mu mangling lekko utrudni, to mu jeszcze troche pograsz na nerwach haslem do polaczenia (po zmanglowaniu programu obsfucatorem nie bedzie banalne skumac, ze naprawde haslo brzmi wlasnie tak..)

minusy:

  • jesli ktos wie jak wyciagnac haslo z zaszyfrowanego app.config, to nie bedzie sie bawil, tylko od razu zacznie tak samo, i bardzo szybko znajdzie ostateczny connstring. co najwyzej usmieje się z hasla-żartu do polaczenia i bedac w dobrym humorze, zrobi mniej szkód, albo popełni błędy pozwalające dowiedziec się kto to był..

a tak bardziej na serio..
Jesli obawiasz się, że użytkownik wiedzący za dużo może Ci zaszkodzić, to znaczy, że już teraz wiesz że architektura Twojego systemu jest "zła".
Jeśli obawiasz się podawać komuś haslo do Twojej bazy, nawet pomimo nadania odpowiednich uprawnien po jej stronie, to znaczy ze Twoj program nie powinien operować na tej bazie. Niestety to jest dokladnie tak proste. Zamiast gadac z bazą bezpośrednio, musisz mieć wtedy jakiś "izolator", cos z czym Twoj program (albo oszalały użytkownik) będzie mógł dowolnie rozmawiać, i tylko ten "izolator" będzie miał prawo dotykac bazy. "Izolator", czyli jakies serwer stojący u Ciebie w domu czy firmie, na którym bedzie chodzic Twoja usługa, nie wazne czy to faktycznie program czy grupka webservice'ow. Serwer stojacy "pod Twoja ręka" bedzie "gwarantowal" bezpieczenstwo kodu, wiec w nim bedziesz mogl uzywac hasel do bazy, i ich ochrona bedzie sprowadzona do ochrony serwera-izolatora przed wlamaniem lub kradzieza fizyczna.. To tyle.. chyba juz "czaisz" wizję..

A jesli sie nie obawiasz az tak, to sie nie obawiaj. Jakiekolwiek pierwsze lepsze rozwiazanie, czy z szyfrowanym app.config, czy z dotsfucatorem, czy z czymkolwiek co po prostu nie pozwoli odczytac hasla przez otworzenie .exe w Notepad'zie - bedzie wystarczajaca, poniewaz i tak NIE BEDZIE wystarczajace dla osoby wiedzacej o co tak naprawde chodzi..

PS. powyzej jest moj komment "to bylo do massther'a, prawda? tez mialem tak ochote odpisac, ale sie powstrzymalem.." - powstrzymalem, bo stwierdzilem, ze warto wyelaborowac no i napisalem -tego- posta.. uzywanie/nieuzywanie akurat tego co zaproponowal massther, jest zalezne od tego jak bardzo autor sie obawia i jak bardzo musi zabezpieczyc dane. na scriptkiddie oraz uzytkownikow-idiotow-z-glupimi-pomyslami, szyfrowany app.config wystarczy w zupelnosci

0

Bartosz Wójcik przecież nie polecam nikomu swojego rozwiązania, dlatego nie rozumiem Twojego oburzenia... Teoretycznie użytkownik mógłby znać hasło do bazy danych, ale ja jako administrator odpowiadam za tą bazę danych. Jeżeli użytkownik ma dostęp tylko przez program to w razie W jestem wstanie na podstawie logów udowodnić, że nieprawidłowe dane są wynikiem jego działań. Chociaż w tym momencie wpadłem na pewien pomysł...

0

Podepnę się delikatnie pod temat jeżeli pozwolicie, ponieważ też nie do końca rozumiem sposób na zabezpieczenie danych przed nielegalnym dostępem do nich.
Dajmy na to, że mamy taka strukturę:
Komputery kliencie komunikują się z serwerem tylko poprzez WCF. WCF Host po stronie serwera ma dostęp do pliku app.config który zawiera usera i hasło dostępu do bazy SQL. W bazie mamy np. dwie tabelę pierwszą z użytkownikami (login, hasło) druga z adresami zamieszkania.
Komputer kliencki podaje login i hasło użytkownika. Przekazuje te dane do WCF Host, ten poprzez użytkownika z app.config uzyskuje dostęp bazy. Następnie przeszukuje tabelę z użytkownikami i przekazuje do stacji informację o dostępie logowanego użytkownika do bazy. I teraz się pojawia problem z ochroną danych w tabeli z adresami zamieszkania. Ponieważ aplikacja kliencka może oczywiści podawać np. tylko rekord z ID klienta zalogowanego ale jeżeli w taki sam sposób zaloguje się aplikacja "obca" to nic nie stoi na przeszkodzie, żeby wykonała select który zwróci wszystkie rekordy z tabeli 'adresy zamieszkania'.
Pewnie problem bym rozwiązał poprzez brak dostępu użytkownika z app.config bezpośrednio do tabel a dał mu tylko dostęp to procedur składowania które filtrowały by dane dostępne tylko dla użytkownika zalogowanego np.po jego ID. Natomiast nie jestem pewien tego rozwiązania - nie projektowałem nigdy rozwiązań WEBowych z dostępem dla użytkowników spoza firmy.

Pozdrawiam,
Zoritt

0
  1. komunikacja między hostem wcf a klientem może być szyfrowana oraz niezależnie wysyłana wiadomość może być zaszyfrowana i podpisana cyfrowo - definiuje się to w configu w sekcji binding
  2. usługi WCF po autentykacji powinny dokonywać również autoryzacji przy odpytywaniu o dane (czyli Kowalskiemu nie zwracać danych Nowaka)
  3. zabezpieczenie hasła w configu hosta, który jest na serwerze i to dostęp do serwera musi być przede wszystkim chroniony, szyfrowane hasło w configu jest utrudnieniem dla potencjalnego włamywacza
  4. zazwyczaj bazę danych stawia się na osobnej maszynie, która nie jest wystawiana na świat, czasem wręcz połączona tylko z maszyną, gdzie stoi warstwa serwisów. W którymś momencie musisz komuś zaufać. Warstwa serwisów jest bramą, która ma uniemożliwić nieuprawniony dostęp do danych. Komunikację między serwisami a bazą prowadzisz bezpiecznym kanałem, natomiast to logika aplikacji (w tym przypadku serwisu) pozwala danemu użytkownikowi pobrać tylko te dane do których jest uprawniony.
    Komunikację z bazą możesz ograniczyć np. do określonych IP, możesz zmienić jej port domyślny i co tam jeszcze dasz radę ustawić na firewall, więc nawet wykradzenie loginu/hasła może być niewystarczające aby dostać się do bazy.
  5. hasła w bazie zaszyfrowane lub trzymane tylko hash
0

Dziękuję za odpowiedź. Mniej więcej tak sobie to wszystko zaprojektowałem.
ale :-)

  1. "podpisana cyfrowo" - niezależna wiadomość?
  2. Aplikację też podpisać cyfrowo? Chociaż muszę przyznać, że nie do końca rozumiem jak to ma działać.
  3. "usługi WCF po autentykacji powinny dokonywać również autoryzacji przy odpytywaniu o dane" - mogę poprosić o dwa zdania naprowadzające?

Pozdrawiam,
Zoritt

0
  1. Szyfrowaniem i podpisywaniem wiadomości zajmuje się wcf (jeśli obie końcówki są w wcf), trzeba tylko włączyć opowiednie opcje w config, sekcja binding/security/...
  2. Którą? możesz swoje assembly, z których składa się aplikacja kliencka podpisać/przypisać tzw. strong name http://msdn.microsoft.com/en-us/library/wd40t7ad.aspx
  3. Autentykacja to proces uwierzytelniania użytkownika, czyli czy Jan Kowalski, to na prawdę Jan Kowalski. Autoryzacja, to weryfikacja czy użytkownika ma uprawnienia do zasobu. Czyli czy Jan Kowalski może wykonać metodę X, czy Kowalski może odpytać o dane Malinowskiego etc. Są jakieś mechanizmy na poziomie WCF, są mechanizmy związane z claims, można też na własną rękę się z tym bawić.
    U ciebie klient podaje login+pass, po tym autentykujesz użytkownika. Musisz mu wystawić jakiś token (nr sesji, jakiś kod, którym będzie posługiwał się przy dalszej komunikacji z kolejnymi usługami wcf'a). Dodatkowo możesz także wymagać podania loginu czy id użytkownika. Kolejny request zawiera token, sprawdzasz czy jest on aktualny i czy dla danego użytkownika (np po IP, czy dodatkowo podanym loginie lub id usera). Dalej weryfikujesz czy ten user odpytuje się o dane do których powinien mieć dostęp.
    Lub tak tworzysz usługi wcf, aby nie zminimalizować (lub wyeliminować) prawdopodobieństwo odpytania o nieuprawnione dane.
    Czyli nie piszesz usługi PobierzWniosek(int idWniosku), tylko PobierzMójWniosek().
0

Dzięki wielkie. Powoli nadchodzi czas zamiany teorii w kod :-)

Pozdrawiam,
Zoritt

1 użytkowników online, w tym zalogowanych: 0, gości: 1