BETA
Aby się zalogować, najpiew wybierz portal.
Aby się zarejestrować, najpiew wybierz portal.
Podaj słowa kluczowe
Słowa kluczowe muszą mieć co najmniej 3 sąsiadujące znaki alfanumeryczne
Pole zawiera niedozwolone znaki

Baza wiedzy











Bezpieczeństwo aplikacji mobilnych opartych na .NET Compact Framework

28-06-2004 18:34 | Dąbek

I. Podstawowe zabezpieczenia urządzeń mobilnych

Zanim przejdziemy do wymagań bezpieczeństwa naszej aplikacji powinniśmy rozważyć najpierw, w jaki sposób moglibyśmy zabezpieczyć nasze urządzenie. Praktycznie każde przedsiębiorstwo, które miałoby używać aplikacji mobilnych, chciałoby wprowadzić takie zabezpieczenia, aby użytkownicy niewiedzący nic na ich temat nie musieli się o nie martwić. Jest to szczególnie ważne, ponieważ do tej pory urządzenia przenośne (mobilne) były używane wyłącznie jako organizery i w większości przypadków nie miały one zbyt dużych zabezpieczeń. Wydaje się to nieco dziwne i zaskakujące. Przecież na urządzeniach tych trzymane były i nadal są prywatne dane, e-maile i listy kontaktów, które mogłyby być informacjami bardzo pożądanymi przez konkurencję. Nowe generacje urządzeń zapewniają kompleksową ochronę połączeń oraz rozwiązania dla ochrony lokalnie przechowywanych danych. Do zabezpieczeń tych należą m.in.:

  1. Autentykacja użytkownika

  2. Używanie oprogramowania antywirusowego

  3. Stosowanie Firewall’i

II. Ochrona bezprzewodowej transmisji danych

Z naszą siecią korporacyjną możemy łączyć się w dwojaki sposób – za pomocą sieci przewodowych lub bezprzewodowych. Dla nielicznych aplikacji na urządzeniach mobilnych możemy zainstalować kartę Ethernetową i używać dla nich zwykłego połączenia do sieci LAN. W większości przypadków będziemy jednak wykorzystywać połączenie bezprzewodowe.

Najpowszechniej używanym protokołem w bezprzewodowej transmisji danych jest protokół 802.11b. Uczeni z Uniwersytetu Kalifornijskiego w Berkley udowodnili, że algorytm Wired Equivalent Privacy (WEP) o statycznym kluczu współdzielonym, używany w tym protokole do zabezpieczenia transmisji danych, jest łatwy do złamania. Ciągle trwają prace nad kolejną wersją tego protokołu WEP2, która ma wypełnić luki w zabezpieczeniach swojego poprzednika. Różne firmy wypuściły tymczasem na rynek wiele rozwiązań, które dopóki nie pojawi się nowy standard, mogą być znakomitymi jego substytutami. Dobrym przykładem może tu być RSA Security bazujący na technologii zwanej szybkopakietowym kluczowaniem (ang. fast-packet keying). Technologia ta eliminuje słabość klucza w standardzie 802.11b.

Problem pojawia się, gdy jesteśmy zmuszeni używać pierwszej wersji standardu, a aplikacja wymaga bezpiecznej komunikacji. Jednak nie jest to sytuacja bez wyjścia. Trudność tę omijamy stosując wirtualne sieci prywatne (VPN) lub Secure Socket Layer (SSL).

Wymianę danych poprzez protokół SSL umożliwiają nam klasy WebRequest i WebResponse. Chęć skorzystania z tego protokołu wymusza na nas rozpoczynanie adresu URL od https:// zamiast od http://. Spełnienie tego warunku sprawi, że transmisja zostanie automatycznie przełączona na transmisję szyfrowaną. Na marginesie należałoby również wspomnieć tu, że poprzez SSL możemy mieć również dostęp do usług XML Web services.

Urządzenia pracujące w terenie łączą się z Internetem przy pomocy połączeń dial-up lub otwartych na długi czas połączeń bezprzewodowych, takich jak TCP/IP poprzez wspomniane wcześniej GPRS lub CDMA2000. Aby zabezpieczyć transmisję danych poprzez Internet wskazane byłoby utworzenie bezpiecznego kanału. Kanał ten tworzymy przy pomocy jednej z dwóch wspomnianych już wcześniej technologii: VPN lub SSL

III. Autentykacja i autoryzacja klientów mobilnych

W każdej aplikacji klient-serwer mechanizm autentykacji i autoryzacji zaimplementowany po stronie serwera do weryfikacji i identyfikacji klientów mobilnych ma kluczowe znaczenie dla bezpieczeństwa. Autentykacja jest procesem identyfikacji klienta wysyłającego żądanie do serwera. Po poprawnym zidentyfikowaniu klienta następuje proces autoryzacji, w którym ustalane jest, jakie prawa ma dany klient na serwerze. Autoryzacja kontrolowana jest przez mechanizmy takie, jak np. system plików NTFS lub system praw dostępu w SQL Server.

W artykule tym skupiono uwagę jedynie na mechanizmach autentykacji wbudowanych w serwer IIS. Na serwerze tym działają następujące rozwiązania dla połączeń:

  • połączenie z usługami XML Web service na serwerze Windows’owym;

  • używanie zdalnego dostępu do danych (RDA) z SQL Server CE;

  • używanie łączenia replik z SQL Server CE;

  • dostęp do SQL Server używając XML poprzez HTTP;

  • połączenie z witrynami serwera IIS używając klas System.Net.WebRequest i WebResponse;

  • Ze względu na to, iż urządzenia z systemem Windows CE nie wspierają Digest Authentication, Kerberos Authentication i Klient Certificate Authentication dostępne mamy tylko trzy formy autentykacji w serwerze IIS, które możemy użyć:

    • Autentykacja anonimowa

    • Autentykacja podstawowa

    Uwaga: Wadą tego rozwiązania jest konieczność przesyłania użytkownika i hasła poprzez sieć. Zaleca się przesyłanie tych parametrów w kodowaniu base64, jednak nie zapewnia to bezpieczeństwa naszych danych. Jeśli zdecydowaliśmy się na podstawową autentykację powinniśmy zawsze używać protokołu SSL (SSL wraz z podstawową autentykacją jest dziś najpowszechniej stosowaną metodą zabezpieczenia przesyłanych danych poprzez sieć Internet).

    • Zintegrowana autentykacja systemowa

    Uwaga: Metody tej nie możemy stosować poprzez firewall’e i serwery proxy, co sprawia, że nie nadaje się ona dla aplikacji internetowych i nie powinna być implementowana w tego typu rozwiązaniach (wyjątkiem są aplikacje wykorzystujące VPN przy połączeniach z Internetu).

    1. Dostarczanie parametrów logowania w aplikacjach .NET Compact Framework

    Używając klasy System.Net.WebRequest parametry logowania dostarczamy w instancji klasy NetworkCredential dołączonej do obiektu WebRequest jako jego właściwość:

    WebRequest zapytanie = WebRequest.Create(adresUrl);
    NetworkCredential _params = new NetworkCredential(“Marcin”, “MyPaSSw0rd”, “”);
    zapytanie.Credentials = _params;
    try
    {
         WebResponse wynik = zapytanie.GetResponse();
    }
    catch (Exception exp)
    {
         MessageBox.Show(exp.Message);
    }

    Logując się do zasobu wymagającego podstawowej autentykacji w parametrach konstruktora NetworkCredential podajemy użytkownika i odpowiadające mu hasło. Jeżeli zaś logujemy się na witrynie używającej zintegrowanej autentykacji systemowej, musimy podać dodatkowo jako trzeci parametr nazwę domeny (zakładamy, że nasze urządzenie mobilne znajduje się w tej samej domenie sieciowej).

    W powyższym przykładzie użytkownik i hasło podane zostało bezpośrednio, aby kod był przejrzysty i prosty. W rzeczywistości dobrym nawykiem jest, aby dane te czytane były z zewnętrznego źródła.

    W zależności od wymagań naszej aplikacji możemy założyć, aby wszyscy użytkownicy aplikacji używali jednego konta systemowego lub aby każdy użytkownik posiadał własne konto w systemie. Niewątpliwą zaletą drugiego rozwiązania jest to, że użytkownik podczas logowania jest identyfikowany jednoznacznie, wadą zaś – bardzo uciążliwe zarządzanie duża ilością kont systemowych.

    Przy korzystaniu tylko z jednego konta systemowego do autentykacji użytkownika mobilnego możemy pokusić się o „zaszycie” użytkownika i jego hasła w kodzie aplikacji. Jeżeli każdy użytkownik ma swoje własne konto, dane do autentykacji muszą być ustawione dla każdego urządzenia oddzielnie i przechowywane w bezpieczny sposób. Nie ma tu mowy o „zaszywaniu” ich w aplikacji, gdyż dla każdego urządzenia trzeba by było oddzielnej wersji programu z innymi danymi. Tak długo jak urządzenie jest zabezpieczone przy pomocy silnego hasła lub innych sposobów autentykacji użytkownika możemy zachowywać nazwę użytkownika i odpowiadające mu hasło w pliku jako czysty tekst. Dla większego bezpieczeństwa zalecane jest mimo wszystko zachowywanie tych danych w pliku w postaci zaszyfrowanej.

    2. Autoryzacja użytkowników mobilnych

    Zaraz po tym jak aplikacja mobilna wysyłająca żądanie do serwera przejdzie pomyślnie proces autentykacji, musi zostać jeszcze poddana autoryzacji. Jak już wspomniałem wcześniej użytkownik, który pomyślnie przeszedł proces autentykacji loguje się do systemu serwera jako użytkownik o ściśle określonej tożsamości. Możemy tak skonfigurować konto użytkownika, aby znajdowało się ono w różnych grupach logowania skojarzonych z różnymi poziomami uprawnień. Nie należy dodawać użytkowników mobilnych do grupy Administratorów, ponieważ grupa ta posiada dużo większe uprawnienia niż użytkownik mobilny powinien posiadać, aby wywołać i wykonać funkcje potrzebne dla naszej aplikacji. Powinniśmy zawsze starać się nadać użytkownikom mobilnym tylko taki poziom uprawnień, aby byli w stanie wywołać i wykonać funkcje dla nich przeznaczone.

    Dla przykładu, użytkownik mobilny wywołujący usługę XML Web service loguje się na serwerze IIS jako szczególny użytkownik systemu Windows. Jeśli tzw. Web–metoda Web service’u odwołuje się do serwera bazy danych SQL Server, musimy użyć w niej kontrolek pozwalających na dostęp i pobranie danych z tej bazy. Należy pamiętać, aby nie dodawać konta systemowego użytego do zalogowania się użytkownika na serwer do grupy db_Admin mającej uprawnienia administratora. Zamiast tego powinniśmy skonfigurować specjalne konto, które umożliwia użytkownikowi dostęp tylko do szczególnych tabel (a nawet szczególnych kolumn) potrzebnych do prawidłowego działania aplikacji. Ustawiamy jako domyślne jedynie możliwość czytania danych, a tylko w szczególnych przypadkach, jeżeli jest to naprawdę potrzebne, możemy ustawić również możliwość modyfikacji.

    3. Zabezpieczanie XML Web Services

    Aplikacje napisane na platformę .NET Compact Framework i wykorzystujące usługi XML Web services wykorzystują protokół HTTP. Mechanizmy używane przy podstawowej autentykacji są aktualnie częścią HTTP i są niezależne od dostawcy oprogramowania. Niezależność ta sprawia, że możemy używać podstawowej autentykacji niezależnie od tego czy używamy serwera Windows z uruchomionym serwerem IIS, czy też z uruchomionym innych serwerem Web’owym jak np. Apache. Aby szyfrować przesyłane dane i uniemożliwić ich odczytanie przez osoby nieupoważnione powinniśmy używać protokołu SSL. Jako alternatywę możemy użyć zintegrowanej autentykacji systemowej do identyfikacji klienta mobilnego na serwerze Windows z uruchomionym serwerem IIS. Aby móc skorzystać z takiej możliwości nasza aplikacja powinna działać wewnątrz sieci Intranet i ma dostęp do usług XML Web service tego serwera.

    Kiedy dodajemy do naszego projektu tzw. Web–referencję do Web service’u wymagającego autentykacji, system zapyta nas o dane logowania.

    Visual Studio .NET używa ich, aby uzyskać z serwera język opisu Web service’u (Web Service Description Language - WSDL) jednoznacznie definiującego nasz Web service. Dane te nie są nigdzie zapisywane w kodzie naszej aplikacji. Wynika stąd, że nadal musimy używać obiektu System.Net.NetworkCredential podczas łączenia się z serwerem usług.

    Weźmy pod uwagę następujący przykład. Jest to prosta aplikacja okienkowa zawierająca dwa pola tekstowe do wpisywania użytkownika i odpowiadającego mu hasła oraz przycisk, który po naciśnięciu odpytuje Web service. W okienku umieszczona jest również etykieta, na której wyświetlane są efekty odpytania Web service’u przez naszą aplikację lub komunikat błędu w przypadku zgłoszenia wyjątku. Nasz projekt posiada referencję do Web service’u, który został skonfigurowany tak, aby używał podstawowej autentykacji. Web service posiada tylko jedną metodę widoczną z zewnątrz:

    [WebMethod]
    public string InfoOUzytkowniku()
    {
         return „Witam uprawnionego użytkownika! Użyte konto do logowania: ”
              + System.Threading.Thread.CurrentPrincipal.Identity.Name;
    }

    Kod obsługujący zdarzenie Click przycisku na postać:

    private void btnPobierzInfo_Click(object sender, System.EventArgs e)
    {
         MojWebService.MojWebService myWS = new MojWebService.MojWebService();
         NetworkCredential _params = NetworkCredential(tbUser.Text, tbPass.Text);
         myWS.Credentials = _params;
         try
         {
              lbOdpowiedz.Text = myWS.InfoOUzytkowniku();
         }
         catch (Exception exp)
         {
              lbOdpowiedz.Text = exp.Message;
         }
    }

    Funkcja btnPobierzInfo_Click tworzy nową instancję klasy proxy Web service’u, MojWebService. Następnie tworzony jest obiekt NetworkCredential i ustawiany jest on jako właściwość Credentials instancji klasy proxy Web service’u. W przypadku, gdy użytkownik poda złego użytkownika i/lub hasło wywołanie metody zgłasza wyjątek z wiadomością „The remote server returned an error: (401) Unauthorized” tak jak to pokazano na rysunku 3. Jeżeli zaś podano poprawne dane, Web service zwraca łańcuch znaków identyfikujący użytkownika systemowego użytego podczas logowania na serwer. Wynik jest podobny do tego przedstawionego na rysunku 4.

    Rys 3. Wyjątek zgłaszany przy złych danych logowania

    Rys 4. Łańcuch znaków zwrócony przez metodę InfoOUzytkowniku

    4. Autentykacja przy użyciu nagłówków SOAP

    Kolejną opcją autentykacji jest przekazywanie danych poprzez nagłówek SOAP w żądaniu wysyłanym do Web service’u. Jeśli używamy tego procesu, nie powinniśmy implementować autentykacji i autoryzacji używając możliwości serwera IIS. Zamiast tego przekazujemy wszystkie parametry w kodzie metody Web service’u. Konsekwencją powyższych założeń jest to, że ten sposób autentykacji jest uniwersalny i działa niezależnie od typu serwera. Jeśli używamy serwera IIS powinniśmy ustawić autentykację na autentykację anonimową.

    Aby napisać Web service używając ASP .NET wymagającego nagłówków SOAP, po pierwsze definiujemy klasę dziedziczącą z klasy System.Wes.Services.Protocols.SoapHeader definiującą obiekt przekazywany w nagłówku SOAP. Następnie deklarujemy publiczne atrybuty określonego typu wewnątrz tej klasy.

    using System;
    using System.ComponontModel;
    using System.Web;
    using System.Web.Services;
    using System.Web.Services.Protocols;
    namespace NETCF_SOAPWebService
    {
         public class NaglowekAutoryzacji : SoapHeader
         {
              public string Username;
              public string Password;
         }
         public class SOAPWebService : System.Web.Services.WebService
         {
              public NaglowekAutoryzacji TokenAutoryzacji;
              ...
         }
    }

    Następnie każdą Web-metodę, w których wymagamy, aby klient przekazał obiekt AuthHeader w nagłówkach SOAP oznaczamy je przy pomocy atrybutu SoapHeader. Pierwszy parametr jest nazwą publicznego pola w klasie, która definiuje typ nagłówka.

    [WebMethod(Description=
    ”Ta metoda wymaga nagłówka SOAP podanego przez wywołującego”)]
    [SoapHeader(“TokenAutoryzacji”, Direction=SoapHeaderDirection.In)]
    public bool Autentykacja()
    {
    if (TokenAutoryzacji == null)
    {
              throw new Exception(“NaglowekAutoryzacji nie został podany w SOAP”);
    }
    if ((TokenAutoryzacji.Username==“Marcin”)&& (TokenAutoryzacji.Password==“MyPaSSw0rd”))
              return true;
    else
              return false;
    }

    W powyższym przykładzie drugi parametr ustala właściwość kierunku przekazywania obiektu SoapHeaderAttribute, który jest jedną z wartości typu wyliczeniowego SoapHeaderDirection. Wartości tego typu wyliczeniowego pokazane są w Tabeli 1.

     

    Wyliczenie

    SoapHeaderDirection

    Opis

    In

    Nagłówek jest wysyłany od klienta do serwera

    InOut

    Nagłówek jest przesyłany w obie strony do serwera i do klienta

    Out

    Nagłówek jest wysyłany od serwera do klienta

    Fault

    Nagłówek jest wysyłany do klienta tylko wtedy, gdy metoda XML Web service’u zgłosiła wyjątek

    Tabela 1 Typ wyliczeniowy SoapHeaderDirection

    SoapHeaderAttribute może być używany do oznaczania metod w XML Web service tak jak to pokazano w poprzednim przykładzie. Ponadto może być on używany do oznaczania metod w klasach proxy po stronie klienta. W tym przypadku SoapHeaderDirection.Fault nie jest wspierany – jeśli metoda po stronie klienta zgłosi wyjątek, nie jest on propagowany z powrotem do serwera jako wyjątek SOAP.

    Po stronie klienta publiczne pole NaglowekAutoryzacji jest widoczne poprzez WSDL dla Web service’u. W momencie gdy dodajemy Web-reference do Web service’u generowany jest kod zawierający definicję klasy NaglowekAutoryzacji i klasy proxy, która jest generowana dla Web service’u i zawiera właściwość NaglowekAutoryzacjiValue. Właściwość ta jest używana do ustawienia odpowiedniego nagłówka SOAP w kodzie klienta. Klient tworzy instancję klasy NaglowekAutoryzacji, po czym ustawia właściwość NaglowekAutoryzacjiValue klasy proxy, aby wskazywała na tę instancję. Na przykład poniższa metoda tworzy instancję klasy proxy Web service’u, a następnie wywołuje metodę Autentykacja Web service’u przekazując instancję klasy NaglowekAutoryzacji w nagłówku SOAP:

    private void Pobierz()
    {
         SOAPWebService.SOAPWebService soapWS = new SOAPWebService.SOAPWebService();
         NaglowekAutoryzacji naglAut = new NaglowekAutoryzacji();
         naglAut.Username = “Marcin”;
         naglAut.Password = “MyPaSSw0rd”;
         soapWS.NaglowekAutoryzacjiValue = naglAut;
         try
    {
              bool odpowiedz = soapWS.Autentykacja();
              ...
         }
         catch (Exception exp)
         {
              MessageBox.Show(exp.Message);
         }
    }

    W powyższym przykładzie użytkownik i hasło podane zostało bezpośrednio w celu uproszczenia kodu. W praktyce dobrym nawykiem jest, czytanie tych danych z zewnętrznego źródła i nie przechowywanie ich w kodzie programu.

    IV. Zabezpieczanie połączeń SQL Server CE

    Jeśli używamy RDA lub replikacji do transferu danych z serwera SQL Server na SQL Server CE na urządzeniu mobilnym, wykorzystywane połączenie jest zarządzane przez IIS. Dane, które transferujemy pomiędzy klientem a serwerem są kompresowane dla zwiększenia efektywności przesyłu, jednak nie są one szyfrowane. Jeśli używamy tych technik na urządzeniu do połączeń przez Internet, powinniśmy rozważyć skonfigurowanie IIS tak, aby używał SSL.

    RDA i replikacja nie wymagają używania SSL powinniśmy jednak użyć tego protokołu w następujących przypadkach:

    • Jeśli skonfigurujemy IIS tak, aby używał podstawowej autentykacji. Jak wyjaśniłem wcześniej nazwa użytkownika i hasło używane w tej technice są przesyłane przez sieć w formacie łatwym do odczytania. Wskazanym jest więc użycie SSL w celu zapobieżenia podglądnięcia tych danych podczas ich wymiany.

    • Jeśli używamy replikacji oraz w przypadku gdy albo SQL Server Publisher albo Distributor polega na SQL Server Authentication. SQL Server Distributor używa SQL Server Authentication jeśli właściwość DistributorSecurityMode jest ustawiona na DB_AUTHENTICATION. Podobnie SQL Server Publisher używa SQL Server Authentication jeśli właściwość PublisherSecurityMode jest ustawiona na DB_AUTHENTICATION. W przypadku gdy używany jest SQL Server Authentication właściwości DistributorPassword i PublisherPassword są przesyłane poprzez sieć w postaci czystego tekstu, co może powodować ryzyko przechwycenia tych informacji.

    • Jeśli używamy RDA i nasza aplikacja wyszczególniła obiekt OLEDBConnectionString zawierający hasło. Metody Pull, Push i SubmitSQL wymagają tego parametru, który jest przesyłany poprzez sieć w postaci czystego tekstu. Może to powodować ryzyko przechwycenia tej informacji.

    V. Zabezpieczanie danych na urządzeniu

    A co z danymi przechowywanymi na urządzeniu? Moglibyśmy pomyśleć, że tak długo jak mamy zabezpieczone urządzenie silnym hasłem, intruz nie ma możliwości przeczytania zawartości tego, co przechowujemy w przypadku, gdy urządzenie zgubimy lub ktoś nam je po prostu ukradnie. Trzeba pamiętać, że samo hasło nie jest dobrym zabezpieczeniem przy ograniczaniu dostępu do danych. Wynika to głównie ze złych nawyków użytkowników zapisujących hasła na kartkach papieru, wyłączających ich sprawdzanie lub ustawiających hasła na takie, które są bardzo łatwe do odgadnięcia, np. pierwsze imię współmałżonka. Użycie silniejszej autentykacji użytkownika, do której należą m.in. rozpoznawanie podpisu lub autentykacja przy pomocy tzw. smart cards zapewnia zwiększenie poziomu bezpieczeństwa przechowywanych lokalnie danych.

    1. Kryptografia na urządzeniu mobilnym

    Są czasem przypadki, że chcemy zaszyfrować względnie małą ilość danych, jak np. plik lub chociażby kawałek tekstu z tego pliku. .NET Framework zawiera przestrzeń nazw System.Security.Cryptography, która posiada klasy zarządzające interfejsem Windows CryptoAPI, pozwalającym na szyfrowanie i deszyfrowanie plików, strumieni danych lub do wykonywania innych czynności takich jak haszowanie, generacja numerów losowych i autentykację wiadomości. Przestrzeń nazw zawiera wiele klas typu CryptoServiceProvider, które pozwalają na użycie następujących algorytmów szyfrujących: DES, DSA, MD5, RC2, RSA, SHA1 lub TripleDES.

    Klas tych nie możemy użyć w wersji 1 .NET Compact Framework. Mimo to w Windows CE zostało zaimplementowane CryptoAPI, jeśli więc chcemy skorzystać z tej możliwości powinniśmy użyć P/Invoke (warstwy pozwalającej na wywołanie funkcji systemowych) aby wywołać i wykonać pewne operacje kryptograficzne.

    Innym sposobem szyfrowania danych na urządzeniu mobilnym jest używanie pośrednich rozwiązań. Dostępnych jest wiele takich rozwiązań zapewniających taką możliwość, jak np. karty pamięci CompactFlash z wbudowanym szyfrowaniem danych lub oprogramowanie wykorzystujące hybrydę wcześniej wspomnianych tzn. połączenie silnej autentykacji z szyfrowaniem danych na kartach pamięci, w pamięci RAM lub w e-mailu. Opis dostępnych produktów dostępny jest pod adresem:

    http://www.microsoft.com/mobile/enterprise/papers/security.asp.

    Szyfrowanie danych jest przezroczyste dla aplikacji napisanych w środowisku .NET Compact Framework. Uniemożliwia to odczytanie danych przechowywanych na urządzeniu, jeżeli wpadnie ono w niepowołane ręce.

    2. Zabezpieczenie baz danych SQL Server CE

    SQL Server CE oferuje nam dwie możliwości zabezpieczenia danych przechowywanych w bazie danych na urządzeniu:

    • zabezpieczenie hasłem podczas połączenia z bazą danych. Należałoby tu również wspomnieć, iż tworzone jest tylko jedno hasło dla tworzonej bazy danych a nie oddzielne hasła dla każdego użytkownika tej bazy,

    • zabezpieczenie danych przechowywanych w pliku bazy danych przy użyciu szyfrowania 128-bitowego. Szyfrowanie te jest w pełni wspierane przez Pocket PC 2002 (i wersje następne) oraz Windows CE .NET. Aby mieć możliwość korzystania z tego typu udogodnień na Pocket PC 2000 musimy pobrać i zainstalować High Encryption Pack for Pocket PC. Dostępny jest on pod adresem:

         http://www.microsoft.com/mobile/pocketpc/downloads/ssl128.asp

    Aby utworzyć bazę danych zabezpieczoną hasłem powinniśmy użyć właściwości password w parametrach połączenia. Jeżeli chcemy z kolei utworzyć szyfrowaną bazę użyjemy właściwości encrypt database. Zauważmy, że możemy stworzyć bazę danych chronioną hasłem, która nie jest szyfrowana. Jednak, jeżeli utworzymy szyfrowaną bazę danych, która nie jest chroniona hasłem, będziemy zmuszeni mimo wszystko używać właściwości password.

    Poniższy przykład sprawdza czy plik bazy istnieje, a jeżeli nie – używa obiektu SqlCeEngine do utworzenia szyfrowanej i chronionej hasłem bazy danych:

    using System.Data.SqlServerCe;
    ...
    if (!System.IO.File.Exists(”\My Documents\MojaBaza.sdf”))
    {
         SqlCeEngine eng = new SqlCeEngine();
    eng.CreateDatabase(“Data Source=\My Documents\MojaBaza.sdf;”+
              “password=mydbpassword;encrypt database=TRUE”);
    }

    W powyższym przykładzie, aby go uprościć, hasło celowo podano bezpośrednio w wywołaniu metody CreateDatabase. Jak już wspominałem wielokrotnie dobrym i zalecanym nawykiem jest wczytywanie go z zewnętrznego źródła.

    Aby uzyskać dostęp do szyfrowanej lub zabezpieczonej hasłem bazy danych powinniśmy użyć właściwości password w parametrach połączenia podawanych jako parametr wywołania metody SqlCeConnection.Open. Poniższy przykład tworzy obiekt SqlCeConnection, otwiera połączenie, wykonuje zapytanie i zamyka połączenie:

    using System.Data.SqlServerCe;
    ...
    public void WstawWiersz(string NumerRej, string Pozycja)
    {
         string connStr = “Data Source=\My Documents\MojaBaza.sdf;”+
              “password=mydbpassword”;
         SqlCeConnection conn = new SqlCeConnection(connStr);
         string insertStr = “INSERT INTO Samochod(NumerRej,Pozycja) Values(‘”
              +NumerRej+”’,’”+Pozycja”’)”;
         SqlCeCommand cmd = new SqlCeCommand(insertStr);
         cmd.Connection = conn;
         try
         {
    conn.Open();
              cmd.ExecuteNonQuery();
         }
         catch (SqlCeException ex)
         {
              MessageBox.Show(ex.Message);
         }
         finally
         {
              conn.Close();
         }
    }

    Po ustawieniu zabezpieczenia hasłem i szyfrowania bazy parametry te nie mogą być zmienione dopóki baza nie zostanie kompaktowana. Aby zmienić te ustawienia powinniśmy użyć właściwości password i encrypt database w parametrach połączenia używanych podczas wywoływania metody Compact instancji klasy System.Data.SqlServerCe.SqlCeEngine.

    VI. Programowanie bezpieczeństwa .NET Compact Framework

    Do tej pory przyjrzeliśmy się dokładniej zabezpieczaniu urządzenia w taki sposób, aby tylko uprawniona osoba mogła go używać, o tym jak autentykować mobilne aplikacje łączące się z naszym serwerem, a także jak chronić dane przechowywane lokalnie na urządzeniu. Wszystko w porządku, ale co z programowaniem bezpieczeństwa? .NET Framework posiada poprawną architekturę bezpieczeństwa opartą na mechanizmach broniących nasze zasoby i kod przed niepowołanymi osobami lub kodem. Mechanizmami tymi są:

    • bezpieczeństwo dostępu do kodu (ang. Code access security) – używa praw dostępu do kontroli odwołań do chronionych zasobów, jak

    • bezpieczeństwo oparte na rolach (ang. Role-based security) – używa referencji dostarczonych przez użytkownika do zarządzania zasobami bazującymi na rolach lub tożsamości użytkownika. Na komputerze desktopowym CLR zapewnia wsparcie dla autoryzacji bazujących na rolach i opartych o konta Windows’owe lub wybraną tożsamość.

    .NET Compact Framework posiada architekturę bezpieczeństwa, która jest podobna do tej w .NET Framework. Przestrzeń nazw System.Security w wersji 1 .NET CF zawiera tylko klasę SecurityPermissionAttribute (i klasy, z których dziedziczy), która została zaprojektowana do użycia wraz z mechanizmem bezpieczeństwa dostępu do kodu. Brak dodatkowych udogodnień w .NET CF jest wynikiem tego, iż Windows CE nie posiada takiego systemu logowania jak wersja desktop’owa Windows’a.

    W wersji 1 .NET CF projektanci nie mają praktycznie żadnych możliwości do zarządzania bezpieczeństwem aplikacji. W przyszłych wersjach będzie zaimplementowanych więcej udogodnień. Obecnie wymagania bezpieczeństwa potrzebują pełnych praw dostępu, aby poprawnie i efektywnie wykonywać kod aplikacji.

    1. Wymagania bezpieczeństwa .NET Compact Framework

    W wersji 1 .NET CF nie istnieją żadne pliki konfiguracyjne, nie ma również żadnych narzędzi, które pozwalają tworzyć lub zarządzać prawami dostępu. Efektem powyższego jest to, że wymagania bezpieczeństwa są z góry ustalone. Wszystkie zasoby należą do grupy kodów All_Code i są ustawione na w pełni zaufane. Nie oznacza to, że nie istnieje tu żadna architektura bezpieczeństwa. Po prostu wszystkie kody uruchamiane są z pełnymi prawami dostępu. Przyszłe wersje .NET CF i/lub implementacje różnych platform będą implementować surowsze warunki bezpieczeństwa, jednak dopóki bezpieczeństwo uwarunkowane jest platformą i uzależnione problemowo, nie jest możliwe przewidzenie, które wymagania bezpieczeństwa będą nałożone na kod w tych wersjach lub na wszystkich platformach. Dla przykładu weźmy pod uwagę dowolne przedsiębiorstwo. W przyszłości będzie ono chciało, aby system operacyjny urządzeń mobilnych nadawał uprawnienia pełnego zaufania dla aplikacji pobranych z jego własnej witryny internetowej, natomiast ograniczał uprawnienia dla programów pobranych z innych lokalizacji. W ten sposób ograniczone zostanie niebezpieczeństwo uruchomienia złośliwego kodu ze zbyt dużymi uprawnieniami na urządzeniu.

    2. Stosowanie bezpiecznego kodowania

    Pomimo że nie możemy programowo zarządzać bezpieczeństwem dostępu do kodu w wersji 1 .NET CF jest wiele zasad, które projektant bezpiecznego oprogramowania powinien mieć na uwadze. Autorzy wirusów wykorzystują słabości w szeroko rozpowszechnionych aplikacjach lub wykorzystują je w sposób niezamierzony przez jej projektanta. Jest wiele rzeczy, które powinniśmy rozważyć w celu uniknięcia wykorzystania naszej aplikacji do destrukcji lub innych złośliwych działań:

    • Bądźmy nieufni dla danych wprowadzanych przez użytkownika. W każdym momencie możliwość wprowadzenia danych może być nadużyta czy też użyta w niewłaściwy sposób. Weźmy jako prosty, aczkolwiek dosadny przykład aplikację bazodanową, w której w pewnym polu tekstowym podajemy nazwę elementu, na podstawie której konstruowane jest zapytanie SQL w postaci:

    „SELECT * FROM Samochody WHERE NumerRej = ‘” + tbNumerRej.Text + „’”

    Wszystko jest w porządku, jeżeli użytkownik poda właściwe dane. Gdy użytkownik poda np. ”any’ DROP TABLE Samochody –”, możemy być niemile zaskoczeni wynikiem zapytania. Przetworzenie zapytania:

    „SELECT * FROM Samochody WHERE NumerRej = ‘any’ DROP TABLE Samochody –’”

    spowoduje usunięcie tabeli Samochody z bazy danych. Aby zapobiec takim nadużyciom powinniśmy używać właściwości MaxLength kontrolek, z których pobieramy dane w celu ograniczenia długość ciągu znaków, jakie użytkownik może podać. Powinniśmy również sprawdzać czy wprowadzone dane spełniają oczekiwany format.

    • Jeśli pozwalamy użytkownikom na zapisywanie danych w plikach piszmy kod, który ogranicza możliwość zapisywania w określonych lokalizacjach lub pod określonymi nawami plików. Nie chcielibyśmy przecież, aby ktoś przypadkiem nadpisał ważny dla nas plik lub plik będący częścią systemu operacyjnego. Zauważmy, że kontrolki OpenFileDialog i SaveFileDialog ograniczają możliwości użytkownika tylko do katalogu My Documents.

    • Jeśli nasza aplikacja wymaga autentykacji użytkownika powinniśmy zastanowić się nad ponowną jego autentykacją po określonym przedziale czasu lub po wykonaniu pewnej liczby operacji. Ograniczy to dostęp do danych niepowołanej osobie, w przypadku gdy zostanie ono nam skradzione lub wyrwane.

    • Jeśli rozpowszechniamy biblioteki lub aplikacje mające dostęp do chronionych zasobów, powinniśmy mieć na uwadze, że w przyszłych wersjach .NET CF zaimplementowane zostaną bardziej restrykcyjne warunki bezpieczeństwa. Wynika stąd, że powinniśmy zaprojektować naszą aplikację czy też bibliotekę tak, aby miała na uwadze bardziej wymagające środowisko w kontekście bezpieczeństwa. Zapewni nam to niewielkie zmiany kodu przy przejściu na późniejsze wersje.

    • Zamknijmy kod wymagający wysokiego bezpieczeństwa w oddzielnym zasobie. Sprawi to, że w przyszłości łatwiej będzie zarządzać bezpieczeństwem, gdyż do każdego zasobu ustalane będą oddzielne prawa dostępu, w takim jednak zakresie na ile on tego wymaga.

    • Piszmy aplikacje niewymagające wysokich zabezpieczeń tak, aby nie potrzebowały uprawnień wyższych niż podstawowe. Jest to ważne, ponieważ w przyszłych wersjach środowiska, w których zaimplementowane zostaną rozszerzenia związane z bezpieczeństwem, będziemy mogli używać naszej aplikacji bazując na podstawowych prawach dostępu.

    VII. Podsumowanie

    Bezpieczeństwo jest tak silne jak silne jest jego najsłabsze ogniwo. Należy więc sprawdzić poziom bezpieczeństwa wszystkich komponentów w rozproszonej aplikacji. Wiele aplikacji mobilnych jest z natury rozpraszanych i wymaga oprogramowania uruchamianego na urządzeniu mobilnym, transmisji danych poprzez sieć, mechanizmów autentykacji i autoryzacji na serwerze oraz oprogramowania uruchamianego na serwerze.

    W artykule tym przedstawiono, w jaki sposób używać mechanizmów autentykacji do kontroli, komu dane jest prawo do używania urządzenia mobilnego, w jaki sposób chronić dane przechowywane na tym urządzeniu, jak szyfrować dane transmitowane przez sieć oraz w jaki sposób dokonywać autentykacji logowania na serwerze IIS. Artykuł ten miał również na celu przyjrzenie się mechanizmom autentykacji, które możemy użyć w zabezpieczaniu Web service’ów.

    Artykuł zakończono przeglądem technik bezpiecznego kodowania (pisania programów). Należy pamiętać, że wersja 1 .NET Compact Framework nie zapewnia pełnej funkcjonalności w pisaniu bezpiecznego kodu tak jak jest to w .NET Framework.

    Literatura:

    [1]     D. Foggon, D. Maharry, Ch. Ullman, K. Watson “Programming Microsoft .NET XML Web Services”, Microsoft Press, 2004

    [2]     A. Wigley, S. Wheelwright “Microsoft .NET Compact Framework”, Microsoft Press, 2003

    Załączniki:

    Komentarze 1

    User 79899
    User 79899
    35 pkt.
    Poczatkujacy
    21-01-2010
    oceń pozytywnie 0
    Ciekawy artykuł, zwraca uwagę na wiele rzeczy, które zazwyczj są pomijane :).
    pkt.

    Zaloguj się lub Zarejestruj się aby wykonać tę czynność.