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











Ochrona danych z użyciem RSA

28-12-2004 01:24 | uzytkownik usuniety
Duża liczba aplikacji zajmuje się przetwarzaniem danych, które chcielibyśmy przechowywać w taki sposób aby niepowołane osoby nie miały do tych danych dostępu. Problem poufności spotyka nas także przy wszelkiego rodzaju aplikacjach sieciowych. Warto wtedy skorzystać z jakiegoś mechanizmu szyfrowania danych, który zabezpieczy dane lub sprawi, ze w sieci nie będą one rozsyłane w jawnej postaci tylko w sposób zakodowany. W artykule przedstawię zaimplementowany na platformie .net klasyczny algorytm s

Wstęp

Duża liczba aplikacji zajmuje się przetwarzaniem danych, które chcielibyśmy przechowywać w taki sposób aby niepowołane osoby nie miały do tych danych dostępu. Problem poufności spotyka nas także przy wszelkiego rodzaju aplikacjach sieciowych. Warto wtedy skorzystać z jakiegoś mechanizmu szyfrowania danych, który zabezpieczy dane lub sprawi, ze w sieci nie będą one rozsyłane w jawnej postaci tylko w sposób zakodowany. W artykule przedstawię zaimplementowany na platformie .net klasyczny algorytm szyfrowania RSA – jego dokładny opis, możliwe zastosowania, sposób użycia.


Teoria

Algorytm RSA został opisany w roku 1977 przez trzy osoby, od których pierwszych liter nazwisk pochodzi sam skrót; byli to: Ron Rivest, Adi Shamir oraz Len Adleman. Na przestrzeni lat teoria algorytmu nie zmieniła się bardzo, zmodyfikowano tylko niektóre algorytmy dokonujące pewnych pośrednich obliczeń, jednakże uzyskiwany efekt jest wciąż bardzo podobny to tego, jaki został opisany na początku.
RSA wykorzystuje w swym głównym założeniu brak efektywnego algorytmu rozkładu liczb całkowitych o bardzo dużych wartościach. Istnienie szybkiego i wykonywalnego algorytmu od razu sprawiłoby, iż opisywany tutaj algorytm stałby się bezużyteczny. W chwili obecnej jest nawet opracowany algorytm rozkładu o złożoności
O((log N)3) przeznaczony dla komputera kwantowego (algorytm Shora) – jednakże do tej pory nie zbudowano maszyny, która z niego mogłaby skorzystać i wielu wierzy, że w przeciągu najbliższych dwudziestu lat nie uda się tego osiągną. Niemniej jednak, należy pamiętać, że sam algorytm nie gwarantuje stuprocentowej pewności poufności danych. Cokolwiek co jest zakodowane w sposób taki, że istnieje metoda na odszyfrowanie danych nigdy nie będzie całkowicie bezpieczne. Pozostawię jednak dygresje filozoficzne na boku i przejdę do opisu samego algorytmu, gdyż uważam, że wiedza o sposobie działania pozwoli na prawidłowe używanie i świadomość tego, co właściwie się dzieje z przetwarzanymi danymi.
W działaniu swym RSA wykorzystuje dwa klucze: kodujący i dekodujący, - są one stworzone na podstawie dwóch wygenerowanych dużych liczb pierwszych, które oznaczymy p i q. Założeniem na wstępie jest, aby

p ? q


 Wyliczany jest następnie ich iloczyn i oznaczany przez

N = p * q

W następnym kroku wybieramy liczbę z przedziału 1 do N, która będzie wraz z wartością N używana jako klucz kodujący. Musi ona spełniać założenie co do względnej pierwszości z iloczynem (p-1)(q-1)

1 < e < N

NWD( e , (p-1)(q-1) ) = 1


Na podstawie wyznaczonej uprzednio wartości należy teraz wyliczyć takie d (wraz z wartością N stanie się kluczem dekodującym), które będzie spełniało zależność, ze reszta z dzielenia iloczyn e*d przez iloczyn (p-1)*(q-1), będzie wynosiła 1:

d * e ? 1 (mod (p-1)(q-1))

Kiedy dokonamy stosownych obliczeń i wyznaczymy te wartości pary liczb (e,N) i (d,N) staną się naszymi kluczami używanymi w procesie szyfrowania czy deszyfrowania.

Przy tak dobranych własnościach wyznaczonych liczb, prawdziwe są równości:
(dodatkowe oznaczenia: n - wartość wejściowa, c - wartość zaszyfrowana)

          [użycie (e,N)]

oraz

         [użycie (d,N) ]

Widzimy więc, ze przy zaszyfrowaniu wartości n kluczem (e,N)  jesteśmy ją w stanie uzyskać z powrotem za pomocą symetrycznego obliczenia. Jednakże to dopiero teoria i dopiero w tym momencie natrafia się na trudności.
Możemy teraz przy odpowiednio dobranych wielkościach liczb mapować naszą informację, którą chcemy zaszyfrować na wartości, podawać je kolejnym przetworzeniom i wysyłać wyniki jako ciąg wyjściowy.
Teoria jednak nic nie mówi o tym jak efektywnie dokonać wszystkich podanych tutaj obliczeń. Do tego wykorzystuje się specjalnie opracowane algorytmy, które w tym artykule jedynie opiszę słownie, aby za daleko od tematu nie odbiegać.
Do wyznaczania początkowych liczb pierwszych najlepiej posłużyć się algorytmem probabilistycznego wyznaczania liczb pierwszych, który dokonuje jedynie pewnej liczby testów mającej na celu dowiedzenie, że wyznaczona liczba nie jest pierwsza – jeżeli dana liczba testów nie podważy tej własności można uznać na pewnym poziomie ufności iż dana liczba jest pierwsza. W praktyce niewielka liczba sprawdzeń jest nam w stanie zagwarantować, że sprawdzana liczba z prawdopodobieństwem jednej milionowej nie jest liczbą pierwszą.
Dokonywanie sprawdzenia względnej pierwszości odbywa się najczęściej rozszerzonym algorytmem Euklidesa arytmetyki modularnej.
Do samego przetwarzania danych, kiedy już posiadamy  obliczone klucze używa się algorytmu szybkiego potęgowania modularnego.

Jeśli klucze są całkowicie tajne algorytm  wydaje się być wiarygodny. Jednak jak zaobserwujemy w przykładach, w niektórych przypadkach zaczyna zastanawiać, czy mając samą wartość N nie jest się w stanie ponownie wyprowadzić wartości e i d. Dla przykładów małych liczb zagadnienie faktycznie wydaje się błahe i odnalezienie tych wartości nie stanowi większego problemu. Jednakże rozkład dużych liczb jest na tyle skomplikowany, że obliczenie tych wartości staje się niezmiernie pracochłonne. Implementacje algorytmu, przyjmują także dodatkowe założenie, że między losowanymi liczbami p i q na początku powinna być różnica kilku rzędów, tak aby ewentualne poszukiwanie tych wartości na podstawie N=(p-1)(q-1) nie zmierzało do przeszukiwania okolic pierwiastka z N.
 

Zastosowania

Spośród wielu możliwych zastosowań, spróbuje przybliżyć te, które mogą wydać się wyjątkowo użyteczne dla działania wielu, nawet prostych aplikacji.

 

Zastosowania – bezpieczna sesja w sieci

Często chcemy w aplikacjach sieciowych udostępnić mechanizm, który uniemożliwi niepowołanym osobom, mającym dostęp do przesyłanych danych, ich interpretację. Opiszę teraz jak powinno wyglądać użycie algorytmu RSA w takim przypadku.

 

 Załóżmy, że naszym celem jest ustanowienie bezpiecznego połączenia między dwoma komputerami w jakiejś sieci. Każdy z nich generuje własny zestaw kluczy do kodowania danych. Teraz celem jest takie korzystanie z tych zestawów wygenerowanych kluczy, aby komputer z którym się komunikujemy miał możliwość interpretowania tego co do niego wysyłamy i jednocześnie jakiekolwiek podsłuchanie transmisji przez osobę trzecią ma uniemożliwiać zrozumienie danych.
 Nie możemy na pewno wysyłać tego klucza, który używany będzie do deszyfrowania informacji, ponieważ jego podsłuchanie, będzie wystarczające do naruszenia bezpieczeństwa. Dlatego też każdy z komputerów spośród własnej pary kluczy wysyła do drugiego ten klucz, którego drugi będzie używać do kodowania informacji wysyłanych do pierwszego.
 


 W przypadku takiej wymiany podsłuchanie umożliwiłoby tylko ewentualne podszycie się pod jeden z komputerów. Jednakże w takiej sytuacji komputery mogą między sobą już przesyłać informacje, którymi dodatkowo ustalą jakiś klucz sesji, który nie będzie widoczny dla podsłuchującego, przez co w tym momencie nie będzie mógł ani podsłuchiwać ani podszywać się.
 Przesyłanie danych wygląda teraz następująco
 

Dla każdej nowej sesji warto losować nowe klucze i używać ich jednorazowo, szczególnie gdy bezpieczeństwo to bardzo ważna rzecz.
Innym podejściem jest zapisywanie kluczy. Do danego odbiorcy można przypisać jakiś konkretny klucz, który używany będzie przez więcej niż jedną sesję. Jest to rozwiązane słuszne, gdy jest pewność, że klucze po stronie klienta są bezpieczne już w sensie fizycznym – że nikt to nich nie będzie miał dostępu.


 

Zastosowania – wiarygodność danych


 RSA może być użyte również do gwarantowania wiarygodności danych. Różne może być rozmieszczenie danych, ale ja przyjąłem w przykładzie rozwiązanie ogólne. W sieci udostępniony może być serwer, który odpowiedzialny jest za przetrzymywanie kluczy deszyfrujących. Zadaniem nie będzie już szyfrowanie, ale gwarancja wiarygodność – jeżeli klucz szyfrujący posiada tylko właściciel można mieć pewność, że jeśli zaszyfruje dane tym kluczem to będą pochodziły właśnie od niego. Takie rozwiązanie uniemożliwia podszywanie się pod inne osoby.
 

 Serwer pełni funkcje ogólnodostępnego zbioru kluczy, ale może być w różnych rozwiązaniach przyjęta lokalność klucza dekodującego, jeżeli zależy nam jedynie na wiarygodności względem jednego odbiorcy.


 

Statystyki z biznesu

 W dzisiejszych systemach stosuje się klucze o złożonościach 1024-4096 bitów. Większość systemów bankowych, jak również portali internetowych, w tym sklepów internetowych używają kluczy złożoności 1024 bitów. Na dzień dzisiejszy jest to pułap, którego złamanie jest niemożliwe. Do niektórych zastosowań wojskowych, szczególnie w USA używa się powszechnie kluczy 4096-bitowych.


 

Implementacja w .net

 Przykładowy program  napisany w C# ma za zadanie pokazać jak prostą metodą udostępniona jest tak złożona funkcjonalność. Przykład wykorzystuje dwie klasy związane z kryptografią, są nimi:

 System.Secutity.Cryptography.RSACryptoServiceProvder
 System. Secutity.Cryptography.Parameters

 Pierwsza z nich implementuje obsługę funkcji, związanych z RSA, druga jest używana do wymiany kluczy. Wygenerowanie nowego klucza sprowadza się do wywołania odpowiedniego konstruktora klasy RSACryptoServiceProvder. Jako parametr przyjmuje ilu-bitowa para kluczy ma zostać utworzona.

[Kod C#]

(…)
RSA = new RSACryptoServiceProvider(1024);
(…)

Od tego momentu mamy dostęp do funkcji szyfrowania i deszyfrowania. Są one następującej postaci:

[Kod C#]

RSA.Encrypt(DataToEncrypt, false);
RSA.Derypt(DataToEncrypt, false);

Pierwszy z parametrów to tablica bajtów do zakodowania/dekodowania. W przykładowym programie szyfrowany jest tekst. Wykorzystana jest dodatkowo klasa konwersji, przez co cały kod jest krótki i zwięzły:

[Kod C#]

 (…)
      private ASCIIEncoding Converter = new ASCIIEncoding();
      private byte[] encryptedText = null;
(…)
      byte[] dataText = Converter.GetBytes( txtInput.Text );
      encryptedText = RSAEncrypt(dataText,RSA.ExportParameters(false));
 (…)

 Funkcje RSAEncrypt I RSADecryt to wydzielone specjalnie przeze mnie fragmenty, które mają na celu zwrócenie uwagę na pewien szczegół. Metoda klasy RSACryptoServiceProvider o nazwie ExportParameters zajmuje się wydzieleniem wygenerowanych kluczy, tak by kolejna instancja klasy mogła korzystać z tych samych kluczy. Może to być w tym momencie także przesłanie kluczy przez sieć – w przykładzie po prostu wywołuję funkcję. Funkcja eksportu przyjmuje jeden parametr, który mówi, czy klucz dekodujący ma zostać dołączony do zestawu. Dzięki takiemu rozwiązaniu właściwie nie musimy zastanawiać się co jest naszym kluczem kodującym, co dekodującym:

     

[Kod C#]

encryptedText = RSAEncrypt(dataText,RSA.ExportParameters(false));

decryptedData = RSADecrypt(encryptedText,RSA.ExportParameters(true));

Czyli do fragmentu systemu, który ma tylko kodować dane nie wysyłamy danych o kluczu dekodującym.

 

 

Przykładowy program

Program dołączony do artykułu obrazuje działanie opisanych funkcji. Jest to prosta aplikacja szyfująca oraz deszyfrująca zadany tekst, opierająca się o klucz 1024-bitowy.

 

Podsumowanie

 Jak widzimy, dzieki bardzo prostym operacjom, wybrane klasy w środowisku .net umożliwiają nam łatwe zabezpieczenie danych w naszej aplikacji. Myślę, że warto z całą zasadzą działania zapoznać się i używać nawet w najprostszych aplikacjach siecieowych. Po pierwsze buduje dobre przyzwyczajenia, a po drugie nie obciąża tak bardzo systemu oraz jej implementacja, przy właściwie napisanym programie, sprowadza się do rozbudowania o około dwadzieścia linijek kodu. Myślę, że artykuł przybliżył sposób dzaiałania szyfrowania i sprawi, że Wasze aplikacje będą bezpieczniejsze.

Załączniki:

Podobne artykuły

Komentarze 2

Pająk Leon
Pająk Leon
12 pkt.
Nowicjusz
21-01-2010
oceń pozytywnie 0

Powiatowy
Powiatowy
0 pkt.
Nowicjusz
21-01-2010
oceń pozytywnie 0
pkt.

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