Elektroda.pl
Elektroda.pl
X
Proszę, dodaj wyjątek www.elektroda.pl do Adblock.
Dzięki temu, że oglądasz reklamy, wspierasz portal i użytkowników.

[C#] Plik jako baza danych

Adix3 15 Sie 2012 19:40 4896 11
  • #1 15 Sie 2012 19:40
    Adix3
    Poziom 13  

    Cześć.

    Tworzę aplikację która będzie operować na "kontach". Dla każdego konta będzie z 10 parametrów hasło, login, e-mail... Wszystkie te dane pasuje przechowywać w jakiejś bazie danych. Myślałem nad zastosowaniem oprogramowania SQL Server 2008 R2 Express, jednak mam drobne problemy z konfiguracją, a po resztą trzeba instalować kolejne oprogramowanie. Po resztą baza tego typu ma ograniczenie rozmiaru do 10GB a ja nie wiem czy potrzebuję więcej niż 5MB.

    I tak się zastanawiam czy nie dało by rady zrobić dla mojej aplikacji bazy opartej na pliku binarnym, lub czymś podobnym? Myślałem też nad excelem ale potrzebuję też jakoś te dane zaszyfrować a pliki excela można otworzyć w każdym pakiecie Office. Ma ktoś jakieś rady?

    0 11
  • #2 15 Sie 2012 20:24
    marcinj12
    Poziom 40  

    A gdzie chcesz tą bazę umieścić i ile osób będzie z niej jednocześnie korzystało? Chcesz tylko, żeby użytkownicy logowali się do programu loginem i hasłem, zapisanymi w tej bazie? Jak bardzo chcesz żeby to "hakeroodporne"? Czy jakieś dane będą później zmieniane/wprowadzane do bazy przez użytkowników?

    0
  • #3 15 Sie 2012 21:24
    Adix3
    Poziom 13  

    Baza ta ma być na tym samym komputerze co aplikacja, może nawet w tym samym folderze. Z bazy będzie korzystała tylko ta aplikacja (jeżeli już o to chodzi to byłoby dobrze gdyby mogły dwie aplikacje na raz korzystać ale wiem że w przypadku plików jest to trudne). Jak bardzo ma to być "hakeroodporne" ? najlepiej jak najbardziej odporne :] Tak dane w tej bazie będą modyfikowane przez aplikację.

    0
  • #4 15 Sie 2012 21:37
    marcinj12
    Poziom 40  

    Jeszcze o jedno zapominałem spytać - to ma być aplikacja zainstalowana na jednym stanowisku (komputerze) z której korzystać będzie wiele osób, czy aplikacji będzie zainstalowana na wielu różnych komputerach?

    0
  • #5 15 Sie 2012 21:58
    Adix3
    Poziom 13  

    Tak, będzie zainstalowana na jednym stanowisku.

    0
  • #6 15 Sie 2012 22:45
    marcinj12
    Poziom 40  

    Skoro tylko na jednym stanowisku to ma działać, to chyba faktycznie nie ma sensu instalowanie jakiegoś silnika bazodanowego, a już zwłaszcza SQL Servera, który ma - delikatnie mówiąc - "mały" przerost rozmiaru do funkcji z których skorzystasz...

    Możliwości masz wiele - może wystarczy wykorzystać pliki .settings do zapisania ustawień? Albo własny plik XML? I jakieś szyfrowanie do tego...

    Jeżeli baza danych, to w Visual Studio powinieneś mieć dostępną wersja Compact Edition SQL Servera z prostym edytorem (jak dodajesz do projektu nowy plik bazy danych: Local Database, utworzy w katalogu projektu plik .sdf, który potem możesz skopiować i umieścić razem z programem). Tylko do działania aplikacji potrzebujesz potem przekopiować kilka .dll'ek, ale to już wygooglasz jakie... Taką bazę możesz potem ochronić hasłem.
    Możesz też użyć np. SQLite (z odpowiednim GUI, polecam SQLite Studio) lub nawet bazę danych utworzoną w MS Access i zabezpieczoną hasłem.

    Jeżeli chodzi o szyfrowanie, to jeżeli chcesz zabezpieczyć w bazie hasło czy login, wystarczy prosty algorytm md5. W bazie danych umieszczasz zakodowane nim pola (np. hasło), a to co wpisze użytkownik w programie, kodujesz i porównujesz z tym co jest w bazie.

    Jeżeli chcesz mieć zakodowane jakieś pole, a potem mieć możliwość jego odkodowania, poszukaj któregoś z popularnych algorytmów zaimplementowanych w .NET: DES, 3DES, AES/Rijandel - wadą jest jedynie to, że gdzieś w kodzie musisz zaszyć klucz, więc jak ktoś jest bardzo uparty i zrobi deasemblacje Twojej aplikacji, dopatrzy się kodu z kluczem jak na dłoni. Ale jak ktoś się uprze, to i to go nie powstrzyma, aplikacje .NET nie tak łatwo zabezpieczyć przed inżynierią odwrotną. Zawsze możesz potem aplikację przepuścić przez jakiś Code Obfuscator, jak widać im bardziej chcesz zabezpieczyć aplikację, tym więcej pracy przed Tobą...

    Od biedy możesz wykorzystać kodowanie Base64 (w zasadzie nawet tego szyfrowaniem nazwać nie można) - tekst robi się nieczytelny na pierwszy rzut oka a użycie jest prościutkie, z drugiej strony - równie łatwo go rozpoznać i zdekodować, jak ktoś się choć trochę orientuje o co chodzi...

    0
  • #7 16 Sie 2012 23:18
    Adix3
    Poziom 13  

    marcinj12 napisał:
    Możliwości masz wiele - może wystarczy wykorzystać pliki .settings do zapisania ustawień? Albo własny plik XML? I jakieś szyfrowanie do tego...


    Myślałem nad wykorzystaniem plików binarnych, czytałem w necie, że ich obróbka jest szybsza, bo nie ma konwersji na tekst czytelny dla człowieka. Nie wiem tylko czy w przypadku plików binarnych jest coś takiego jak przejście do nowej linii, bo jeszcze się dokładnie w ich obsługę nie zagłębiałem? Ułatwiło by to sprawę gdyż można by zrobić coś takiego, że nazwy użytkowników były by zapisywane w nowej linii co np. 10 linii, a wiersze pomiędzy tymi nazwami użytkowników były by miejscem na inne dane dotyczące tego użytkownika. Może to zwizualizuję (cyfry oznaczają nr. linii w pliku):

    Code:
    1. Jan Kowalski
    
      2. Hasło
      3. E-mail
      4. Adres
      5. Coś tam
      [...]
    10. Ela Kowalska
      11. Hasło
      12. E-mail
      13. Adres
      14. Coś tam
      [...]
    [...]


    Jednak na rozum to biorąc to w pliku binarnym nie ma czegoś takiego jak nowa linia więc to odpada, chyba że się mylę :P

    Teraz jeszcze pozostaje kwestia bezpieczeństwa przechowywanych danych. Racja loginy i hasła można hashować a potem porównywać, jednak resztę też trzeba by zabezpieczyć, w senie że jak już ktoś będzie grzebał przy pliku to nie mógł za pomocą zwykłego notatnika dokonać zmian. Myślałem też nad szyfrowaniem całego pliku bazy danych. Czyli że działało by to w ten sposób:

    aplikacja odszyfrowuje plik np. algorytmem Rijandel, i odszyfrowane dane przechowuje w pamięci (czyli taki jakby plik przechowywany nie na dysku tylko w pamięci), wykonuje jakieś tam operacje na tych informacjach, dodaje nowego użytkownika, ... a następnie (np. co 15min) ten "plik" z pamięci szyfruje i wynikiem szyfrowania nadpisuje plik bazy. Potem albo dalej operuje na tym wirtualnym pliku w pamięci, albo go usuwa i znowu odszyfrowuje plik bazy danych i zapisuje go do pamięci w celu dalszej obróbki danych (czyli zaczyna się znowu od nowa). Tylko znowu nie wiem czy da się jakoś skopiować taki odszyfrowany plika do pamięci i na tym operować?

    Chyba, że to jest totalnie idiotyczny pomysł i ktoś ma coś innego :D

    0
  • #8 17 Sie 2012 00:11
    McMonster
    Poziom 32  

    Ja bym zastosował wbudowaną serializację danych języka i zapis do pliku, C# na pewno ma taki mechanizm. Zapisujesz całą swoją strukturę danych w kilku liniach do pliku, plik od biedy szyfrujesz wybranym algorytmem. Ewentualnie możesz pobawić się jakąś biblioteką NoSQL.

    Ale nie łudź się, że to będzie bardzo bezpieczne, bo klucz do odszyfrowania tak czy inaczej będzie zapisany w trzewiach aplikacji. Przy szyfrowaniu pliku z danymi i zabezpieczeniu pliku wykonywalnego aplikacji popularnymi metodami możesz liczyć na to, że dane będą bezpieczne dla przeciętnego użytkownika komputera, dobry informatyk i tak będzie w stanie te dane odczytać.

    A teraz chwila na kącik edukacyjny. Plik tekstowy też jest zapisany binarnie, jak wszystko na komputerze. Znak nowej linii to umowny znak lub znaki zakodowane w ASCII, np. w systemie Windows to sekwencja CR LF, czyli liczbowo 13 10. Plik tekstowy to po prostu taki, gdzie wszystkie dane są zapisane binarnie w postaci sekwencjii kodów ASCII, a że z tego ma powstać nowa linia wiedzą edytory tekstu. Gdy mówimy o pliku binarnym, to sam wymyślasz sobie takie sekwencje, np. poszczególne pola danych oddzielasz sobie binarnie sekwencją 10101010, a rekordy 11001100. Pola tekstowe mogą być zakodowane przykładowo w ASCII, możesz wymyślić własny sposób kodowania, masz absolutną dowolność w tym, jak zapisujesz dane. Jedyne, co cię interesuje, to żeby sekwencje do oddzielania danych nie pojawiły się przypadkiem we wprowadzanych danych, ale to można wykryć i je podmieniać przy zapisie i odczycie. I tak oto mamy plik binarny.

    0
  • #9 17 Sie 2012 01:11
    marcinj12
    Poziom 40  

    Adix3 napisał:
    Myślałem nad wykorzystaniem plików binarnych, czytałem w necie, że ich obróbka jest szybsza
    Może jest, może nie - jakie to ma znaczenie dla Twojej aplikacji? Ilu będziesz miał tych użytkowników- 10, 20, może 100?? Nawet jeżeli obróbka plików binarnych jest szybsza, różnicę pewnie zauważysz przy paru milionach rekordów (a przy takich ilościach rekomenduję użycie bazy danych), a i to różnicę rzędu ułamku sekundy, szkoda czasu na ręczna bawienie się w zapis/odczyt plików binarnych. Już lepiej wykorzystać XML, łatwiej się z niego czyta/zapisuje wybrane rekordy w takiej strukturze jak mniej więcej podałeś.

    Albo, jak radzi poprzednik, zastosować serializację, tylko że bez szyfrowania dane zostaną zapisane jawnym tekstem i będzie problem jeżeli będziesz chciał taką bazę potem rozbudować np. o dodatkowe "kolumny" (po dodaniu takowej musisz na nowo plik zserializować, bo stary nie będzie pasował do nowej struktury danych).

    Ja obstaję przy małej, szyfrowanej plikowej bazie danych: stwórz taką w SQLite lub w SQL Server Compact Edition i zabezpiecz ją hasłem.
    Krok po kroku jak to zrobić w Visual Studio:
    1. Utwórz projekt i zapisz go gdzieś na dysku,
    2. Prawym myszy -> Add -> New Item, wybierz Local Database, nazwij ją jakoś i kliknij Add, w kolejnym okienku Cancel.
    3. Klikasz dwa razy utworzony plik .sdf, otworzy się drzewko Database Explorer (jak go nie masz, włącz je w widoku View).
    4. W folderze Tables wybierz prawym Create Table i utwórz tabelę, nazwij ją, dodaj kilka kolumn o odpowiednim typie i zatwierdź OK.
    5. Na utworzonej tabli prawym, Show Table Data i wprowadź kilka rekordów - dla testu.
    6. Teraz, jak wyedytujesz w windowsie taki plik .sdf w notatniku zauważysz, że poza nieczytelnym kodem są zapisane jawnym tekstem wartości niektórych pól - czyli niedobrze...
    7. Wracasz do Visuala, Database Explorer, klikasz prawym plik .sdf i wybierasz Database Properties. W okienku które się pojawi masz trzy opcje: nas interesuje Set Password. Klikasz i podajesz dwa razy nowe hasło (stare zostawiasz puste). Zamykasz, ew. powtarzasz hasło żeby Visual Studio sobie je zapamiętał na czas projektowania.
    8. Ponownie edytujesz plik w windowsie w notatniku - teraz w pliku masz same "krzaki" i bez znajomości hasła lub technik hakerskich ;) niedzielny użytkownik raczej go nie odczyta.
    9. Dalej pracujesz z plikiem jak z normalną baza danych. Hasło musisz zaszyć w connection stringu, więc pozostaje wspomniany problem że gdzieś w aplikacji będzie ono zaszyte, ale to jeż trzeba grzebać w środku. Dla pewności - hasło czy ew. login możesz zaszyfrować w jedną stronę algorytmem md5, tylko pamiętaj, że takiego pola już nie odkodujesz, logując się szyfrujesz to co wpisał użytkownik i sprawdzasz czy taki rekord jest w bazie.

    0
  • #10 17 Sie 2012 21:49
    Adix3
    Poziom 13  

    Ok dziękuję za wszystkie odpowiedzi.

    Mam jeszcze jedno ostatnie pytanie. A mianowicie chodzi o szyfrowanie i bezpieczeństwo z tym związane. Czy np. szyfr symetryczny Rijandel jest ciężko złamać? Załóżmy że klucz nie dostanie się w ręce osoby próbującej wykraść dane, po prostu takie szybkie założenie że szyfruję dane kluczem który tylko ja znam, chcę wiedzieć czy to szyfrowanie można złamać jakoś bez znajomości klucza, a może zajęło by to z 10lat, itp ?

    A jeżeli łatwo złamać ten szyfr to jaki jest lepszy oczywiście z tych obecnych w C#?

    Tak jak pisałem proszę uwzględnić to że osoba dopuszczająca się ataku nie zna klucza no chyba że w wyniku tego ataku odtworzy go jakoś z tych zaszyfrowanych danych, ale to też na pewno trochę zajmuje.

    0
  • #11 17 Sie 2012 22:29
    marcinj12
    Poziom 40  

    Nie zagłębiałem się nigdy w takie szczegóły, ale z szybkiej analizy informacji dostępnych w sieci, np. tutaj wynika, że obecnie preferowany jest AES i jest on praktycznie nie do złamania, więc ja bym użył tego algorytmu.

    Jednak ponownie podkreślę, że jeżeli planujesz zaszyć klucz w aplikacji, to prędzej ktoś będzie próbował go stamtąd odczytać, niż łamać zaszyfrowane dane. Jedyny pewny sposób który mi przychodzi na myśl, to nie trzymać hasła w aplikacji, a prosić użytkownika o jego wpisanie z klawiatury np. przy logowaniu do programu.

    A założenie:

    Cytat:
    Załóżmy że klucz nie dostanie się w ręce osoby próbującej wykraść dane

    jest pewnie najczęstszą przyczyną ich złamania ;P

    0
  • #12 18 Sie 2012 02:00
    McMonster
    Poziom 32  

    Jeszcze szybsza analiza informacji w sieci pozwala stwierdzić, że Rijndael to oryginalna nazwa algorytmu AES. ;)

    Raczej nie piszesz aplikacji dla rządu USA, więc choćbyś użył ROT13, to dane będą bezpieczne w praktyce, bo przy wspomnianym scenariuszu jak ktoś będzie chciał, to wyciągnie klucz zapisany w aplikacji. AES masz pod ręką w bibliotekach C# z tego, co piszesz, więc zastosuj go. Nad dalszymi możliwościami zabezpieczenia można gdybać, ale nie podałeś zbyt wiele informacji na temat tego co to za aplikacja, kto będzie jej używał i jakie dane próbujesz ochronić.

    0