|
Serwis Edukacyjny w I-LO w Tarnowie
Materiały dla uczniów liceum |
Wyjście Spis treści Wstecz Dalej
Autor artykułu: mgr Jerzy Wałaszek |
©2026 mgr Jerzy Wałaszek
|
ProblemNależy opracować niesymetryczny system szyfrowania danych. Symetryczny system szyfrowania to taki, w którym klucz szyfrujący pozwala zarówno szyfrować dane, jak również odszyfrowywać je. Opisane w poprzednich rozdziałach systemy były systemami symetrycznymi. Podstawową wadą systemów symetrycznych jest ścisła konieczność ochrony klucza. Z tego powodu można je było stosować tylko w ograniczonych grupach użytkowników.
W roku 1977 trzej profesorowie z MIT w USA, Ronald L. Rivest, Adi Shamir i Leonard Adleman, opublikowali nowy rodzaj szyfrowania danych, który nazwano od pierwszych liter ich nazwisk systemem RSA. Jest to niesymetryczny algorytm szyfrujący, którego zasadniczą cechą są dwa klucze: publiczny do kodowania informacji oraz prywatny do jej odczytywania. Klucz publiczny (można go udostępniać wszystkim zainteresowanym) umożliwia jedynie zaszyfrowanie danych i w żaden sposób nie ułatwia ich odczytania, nie musi więc być chroniony. Dzięki temu firmy dokonujące transakcji poprzez sieć Internet mogą zapewnić swoim klientom poufność i bezpieczeństwo. Drugi klucz (prywatny, przechowywany pod nadzorem) służy do odczytywania informacji zakodowanych przy pomocy pierwszego klucza. Klucz ten nie jest udostępniany publicznie. System RSA umożliwia bezpieczne przesyłanie danych w środowisku, w którym może dochodzić do różnych nadużyć. Bezpieczeństwo oparte jest na trudności rozkładu dużych liczb na czynniki pierwsze. Przykład: Załóżmy, iż dysponujemy superszybkim komputerem, który jest w stanie sprawdzić podzielność miliarda dużych liczb w ciągu jednej sekundy. Aby złamać szyfr RSA należy rozbić klucz publiczny na dwie liczby pierwsze będące jego dzielnikami. Znajomość tych liczb pozwala rozszyfrować każdą informację zakodowaną kluczem prywatnym i publicznym. Brzmi dosyć prosto. Jednakże nie ma prostej metody rozbijania dużych liczb na czynniki pierwsze. Nie istnieje żaden wzór, do którego podstawiamy daną liczbę i w wyniku otrzymujemy wartości jej czynników pierwszych. Należy je znaleźć testując podzielność kolejnych liczb. Z rozważań o liczbach pierwszych wynika, iż w przypadku dwóch różnych dzielników pierwszych jeden musi leżeć poniżej wartości pierwiastka z danej liczby, a drugi powyżej (dlaczego?). Zatem, aby go znaleźć musimy wyliczyć pierwiastek z rozkładanej liczby, a następnie testować podzielność przez liczby nieparzyste leżące poniżej tego pierwiastka. Statystycznie poszukiwany czynnik pierwszy powinien znajdować się w górnej połówce zakresu od 2 do pierwiastka z n. Ile działań musimy wykonać? Policzmy. Klucz 128 bitowy. Pierwiastek jest liczbą 64 bitową. W zakresie od 2 do 264 co druga liczba jest nieparzysta, zatem jest ich około 264 / 2 = 263. Ponieważ interesuje nas tylko górna połówka, to ilość liczb do sprawdzenia jest dwa razy mniejsza, czyli wynosi 263 / 2 = 262. Ile czasu zajmie naszemu superkomputerowi sprawdzenie podzielności przez około 262 liczb, jeśli w ciągu 1 sekundy wykonuje on miliard sprawdzeń? Odpowiedź brzmi: zajmie to około: 262/109 = 4611686018 sekund = 76861433 minut = 1281023 godzin = 53375 dni = 146 lat Czy sądzisz, że ktoś będzie czekał przez prawie dwa życia na złamanie szyfru? Zatem można podać do publicznej wiadomości liczbę będącą iloczynem dwóch dużych liczb pierwszych i mieć prawie pewność, iż nikt jej nie rozbije na czynniki pierwsze w rozsądnym czasie. Ostatecznie zamiast 128 bitów możemy zwiększyć klucz do np. 1024 bitów, a wtedy czas łamania szyfru liczy się miliardami miliardów… miliardów lat. |
Algorytm RSA składa się z trzech podstawowych kroków:
| I | Znajdź dwie duże liczby pierwsze (mające np. po 128 bitów). Oznacz je jako p i q. Istnieją specjalne algorytmy generujące duże liczby pierwsze, które wykorzystują np. test Millera-Rabina. |
|---|---|
| II | Oblicz:Ø = (p-1)×(q-1)oraz n = p×qLiczby pierwsze p i q usuń, aby nie wpadły w niepowołane ręce. Ø to tzw. funkcja Eulera, n jest modułem. |
| III | Wykorzystując odpowiednio
algorytm Euklidesa znajdź liczbę e, która jest względnie pierwsza z wyliczoną wartością funkcji Eulera Ø (tzn. NWD(e, Ø) = 1) Liczba ta powinna również spełniać nierówność 1 < e < n. Nie musi być pierwsza lecz nieparzysta. |
| IV | Oblicz liczbę odwrotną modulo Ø do
liczby e,
czyli spełniającą równanie: d×e mod Ø = 1Można to zrobić przy pomocy rozszerzonego algorytmu Euklidesa, który umieściliśmy w naszym artykule. |
| V | Klucz publiczny jest parą liczb
(e, n),
gdzie
e nazywa
się publicznym wykładnikiem. Możesz go przekazywać wszystkim zainteresowanym. |
| VI | Klucz tajny to
(d, n),
gdzie
d nazywa
się prywatnym wykładnikiem. Klucz ten należy przechowywać pod ścisłym nadzorem. |
Przykład:
| p = 13 q = 11 |
Wybieramy dwie dowolne liczby pierwsze. W naszym przykładzie nie będą one duże, aby nie utrudniać obliczeń. W rzeczywistości liczby te powinny być ogromne. |
|---|---|
| Ø = 120 | Obliczamy:Ø = (p-1)×(q-1)czyli tzw. funkcję Eulera: Ø = (13-1)×(11-1)
= 12×10
= 120
|
| n = 143 | Obliczamy
moduł n:n = p×q = 13×11 = 143 |
| e = 7 | Wyznaczamy wykładnik
publiczny e.
Ma on być względnie pierwszy z Ø czyli z liczbą 120. Warunek ten spełnia, np. liczba 7. |
| d = 103 | Wyznaczamy następnie wykładnik prywatny, który ma być odwrotnością modulo Ø liczby e, czyli: d×7 mod 120 = 1
Liczbą spełniającą ten warunek jest 103. |
| (7, 143) | Klucz publiczny (e, n). |
| (103, 143) | Klucz tajny (d, n). |
| I | Otrzymujesz od adresata klucz publiczny w postaci pary liczb (e, 0). |
|---|---|
| II | Wiadomość do zaszyfrowania zamieniasz na liczby naturalne t, które muszą spełniać nierówność 0 < t < nMożna tutaj skorzystać np. z łączenia kodów znaków. Oczywiście adresat musi znać użyty przez ciebie sposób przekształcenia tekstu w liczbę, aby mógł on później odtworzyć otrzymaną wiadomość. Zwykle nie ma z tym problemu, ponieważ nadawca i odbiorca stosują wspólne oprogramowanie, które troszczy się za ciebie o takie szczegóły techniczne. |
| III | Na tak otrzymanych liczbach wykonujesz operację szyfrowania i otrzymujesz liczby c = te mod n. |
| IV | Liczby c są zaszyfrowaną postacią
liczb t i przekazuje się je adresatowi wiadomości. Klucz (e, n) umożliwił ich zaszyfrowanie, lecz nie pozwala ich rozszyfrować. |
Przykład:
| e = 7 n = 143 |
Otrzymaliśmy klucz publiczny (e,
n). Przy jego pomocy możemy zakodować liczby od 0 do 142. Zauważ, iż liczby 0 oraz 1 nie zostaną zakodowane (dlaczego?). |
|---|---|
| c = 7 | Załóżmy, iż chcemy przesłać adresatowi zaszyfrowaną liczbę t = 123. W tym celu musimy obliczyć wartość wyrażenia: c = 1237 mod 143 = 425927596977747 mod 143 = 7Wynik jest zaszyfrowaną liczbą 123. Przesyłamy go do adresata. |
| I | Jesteś adresatem zaszyfrowanych wiadomości. Wcześniej wszystkim korespondentom przesłałeś wygenerowany klucz publiczny (e, n), za pomocą którego mogą oni szyfrować i przesyłać ci swoje dane. Otrzymujesz więc zaszyfrowaną wiadomość w postaci liczb naturalnych c, które muszą spełniać warunek: 0 < c < n |
|---|---|
| II | Liczbę c przekształcasz na pierwotną
wartość t, stosując wzór: t = cd mod n |
| III | Z otrzymanej liczby t odtwarzasz wg ustalonego systemu znaki tekstu. Teraz możesz odczytać przesłaną wiadomość. |
Przykład:
|
d = 103 n = 143 c = 7 |
Otrzymaliśmy zakodowaną wiadomość o wartości 7. Jesteśmy w posiadaniu klucza prywatnego, który służy do rozszyfrowywania wiadomości zakodowanych kluczem publicznym. |
|---|---|
| t = 123 | Wykonujemy następujące operacje:t = 7103 mod 143Potęga jest zbyt duża, aby można ją było w normalny sposób obliczyć (języki programowania mają zwykle ograniczenia co do wielkości liczb całkowitych, wyjątkiem jest tutaj Python). Jednakże nas nie interesuje wartość liczbowa potęgi, a jedynie reszta z dzielenia jej przez 143. Możemy więc rozłożyć potęgę na iloczyn składników o wykładnikach równych kolejnym potęgom liczby dwa: 7103 mod 143 = 764+32+4+2+1 mod 143 = (764 mod 143)×(732 mod 143)× (74 mod 143)×(72 mod 143)×7 mod 143 71 mod 143 = 7Do wyliczenia potęgi bierzemy tylko te reszty, które występują w sumie potęg 2: (jeśli byłoby ich bardzo dużo, to każde kolejne mnożenie można wykonać z operacją modulo, dzięki czemu wynik nigdy nie wyjdzie poza wartość modułu) t = 7103 mod 143 = 113×16×113×49×7 mod 143 = 123 |
|
Uwaga: Zanim uruchomisz program, przeczytaj wstęp do tego artykułu, w którym wyjaśniamy funkcje tych programów oraz sposób korzystania z nich. |
| Na podstawie podanych informacji
napiszemy prostą aplikację, która pełnić będzie rolę kompletnego
systemu szyfrowania RSA. Proces szyfrowania i rozszyfrowywania jest identyczny, różni się tylko rodzajem
zastosowanego klucza. Dlatego w aplikacji występują jedynie dwie
opcje: tworzenie kluczy RSA oraz szyfrowanie
RSA. W pierwszym przypadku program generuje dwa klucze,
publiczny oraz prywatny. Należy zapamiętać te dane, gdyż będą one
potrzebne w drugiej opcji do szyfrowania lub rozszyfrowywania.
Proponujemy zastosowanie tej aplikacji do prostej zabawy w klasie.
Tworzymy jedną grupę uczniów, która utworzy klucz publiczny oraz
prywatny. Klucz publiczny przekaże reszcie klasy, klucz prywatny
zachowa dla siebie. Następnie pozostali uczniowie na podstawie
otrzymanych kluczy publicznych mogą kodować swoje dane i przekazywać
je pierwszej grupie, która za pomocą klucza prywatnego dokona
rozszyfrowania wiadomości. Życzymy dobrej zabawy. |
Pascal{
*******************************************************
** Przykładowa aplikacja obrazująca sposób działania **
** asymetrycznego systemu kodowania informacji RSA. **
** ------------------------------------------------- **
** (C)2020 mgr Jerzy Wałaszek **
** I Liceum Ogólnokształcące **
** im. Kazimierza Brodzińskiego **
** w Tarnowie **
*******************************************************
}
program rsa;
// Procedura oczekuje na naciśnięcie
// klawisza Enter, po czym czyści ekran
// okna konsoli
//-------------------------------------
procedure Czekaj;
var
i : integer;
begin
writeln;
writeln('Zapisz te dane i nacisnij Enter');
readln;
for i := 1 to 500 do writeln;
end;
// Funkcja obliczająca NWD
// dla dwóch liczb
//------------------------
function nwd(a, b : integer) : integer;
var
t : integer;
begin
while b <> 0 do
begin
t := b;
b := a mod b;
a := t
end;
nwd := a
end;
// Funkcja obliczania odwrotności
// modulo n
//-------------------------------
function odwr_mod(a, n : integer) : integer;
var
a0, n0, p0, p1, q, r, t : integer;
begin
p0 := 0; p1 := 1; a0 := a; n0 := n;
q := n0 div a0;
r := n0 mod a0;
while r > 0 do
begin
t := p0-q*p1;
if t >= 0 then
t := t mod n
else
t := n-((-t) mod n);
p0 := p1; p1 := t;
n0 := a0; a0 := r;
q := n0 div a0;
r := n0 mod a0;
end;
odwr_mod := p1;
end;
// Procedura generowania kluczy RSA
//---------------------------------
procedure klucze_RSA;
const
tp : array [0..9] of integer
= (11, 13, 17, 19, 23, 29, 31, 37, 41, 43);
var
p, q, phi, n, e, d : integer;
begin
writeln('Generowanie kluczy RSA');
writeln('----------------------');
writeln;
// generujemy dwie różne,
// losowe liczby pierwsze
repeat
p := tp[random(10)];
q := tp[random(10)];
until p <> q;
phi := (p-1)*(q-1);
n := p*q;
// wyznaczamy wykładniki e i d
e := 3;
while nwd(e, phi) <> 1 do inc(e, 2);
d := odwr_mod(e, phi);
// gotowe, wypisujemy klucze
writeln('KLUCZ PUBLICZNY');
writeln('wykladnik e = ', e);
writeln(' modul n = ', n);
writeln;
writeln('KLUCZ PRYWATNY');
writeln('wykladnik d = ', d);
Czekaj;
end;
// Funkcja oblicza modulo potęgę podanej liczby
//---------------------------------------------
function pot_mod(a, w, n : integer) : integer;
var
pot, wyn, q : integer;
begin
// wykładnik w rozbieramy na sumę potęg 2.
// Dla reszt niezerowych tworzymy iloczyn
// potęg a modulo n.
pot := a; wyn := 1; q := w;
while q > 0 do
begin
if(q mod 2) = 1 then wyn := (wyn*pot) mod n;
pot := (pot*pot) mod n; // kolejna potęga
q := q div 2;
end;
pot_mod := wyn;
end;
// Procedura kodowania danych RSA
//-------------------------------
procedure kodowanie_RSA;
var
e, n, t : integer;
begin
writeln('Kodowanie danych RSA');
writeln('--------------------');
writeln;
write ('Podaj wykladnik = '); readln(e);
write (' Podaj modul = '); readln(n);
writeln('----------------------------------');
writeln;
write ('Podaj kod RSA = '); readln(t);
writeln;
writeln('Wynik kodowania = ',
pot_mod(t, e, n));
Czekaj;
end;
// ********************
// ** Program główny **
// ********************
var
w : integer;
begin
randomize;
repeat
writeln('System szyfrowania danych RSA');
writeln('-----------------------------');
writeln(' (C)2012 mgr Jerzy Walaszek ');
writeln;
writeln('MENU');
writeln('====');
writeln('[0]-Koniec pracy programu');
writeln('[1]-Generowanie kluczy RSA');
writeln('[2]-Kodowanie RSA');
writeln;
write ('Jaki jest twoj wybor? (0, 1 lub 2) : ');
readln(w);
writeln; writeln; writeln;
case w of
1 : klucze_RSA;
2 : kodowanie_RSA;
end;
writeln; writeln; writeln;
until w = 0;
end. |
C++/*
*******************************************************
** Przykładowa aplikacja obrazująca sposób działania **
** asymetrycznego systemu kodowania informacji RSA. **
** ------------------------------------------------- **
** (C)2020 mgr Jerzy Wałaszek **
** I Liceum Ogólnokształcące **
** im. Kazimierza Brodzińskiego **
** w Tarnowie **
*******************************************************
*/
#include <iostream>
#include <iomanip>
#include <cstdlib>
#include <ctime>
using namespace std;
// Funkcja czeka na dowolny klawisz i czyści ekran
//------------------------------------------------
void czekaj(void)
{
char c[1];
cout << "\nZapisz te dane\n\n";
cin.getline(c, 1);
cin.getline(c, 1);
for(int i = 1; i < 500; i++)
cout << endl;
}
// Funkcja obliczająca NWD dla dwóch liczb
//----------------------------------------
int nwd(int a, int b)
{
int t;
while(b != 0)
{
t = b;
b = a%b;
a = t;
};
return a;
}
// Funkcja obliczania odwrotności modulo n
//----------------------------------------
int odwr_mod(int a, int n)
{
int a0, n0, p0, p1, q, r, t;
p0 = 0; p1 = 1; a0 = a; n0 = n;
q = n0/a0;
r = n0%a0;
while(r > 0)
{
t = p0-q*p1;
if(t >= 0)
t = t%n;
else
t = n-((-t)%n);
p0 = p1; p1 = t;
n0 = a0; a0 = r;
q = n0/a0;
r = n0%a0;
}
return p1;
}
// Procedura generowania kluczy RSA
//---------------------------------
void klucze_RSA()
{
const int tp[10]
= {11, 13, 17, 19, 23, 29, 31, 37, 41, 43};
int p, q, phi, n, e, d;
cout << "Generowanie kluczy RSA\n"
"----------------------\n\n";
// generujemy dwie różne, losowe liczby pierwsze
do
{
p = tp[rand()%10];
q = tp[rand()%10];
} while(p == q);
phi = (p-1)*(q-1);
n = p*q;
// wyznaczamy wykładniki e i d
for(e = 3; nwd(e, phi) != 1; e += 2);
d = odwr_mod(e, phi);
// gotowe, wypisujemy klucze
cout << "KLUCZ PUBLICZNY\n"
"wykladnik e = " << e
<< "\n modul n = " << n
<< "\n\nKLUCZ PRYWATNY\n"
"wykladnik d = " << d << endl;
czekaj();
}
// Funkcja oblicza modulo potęgę podanej liczby
//---------------------------------------------
int pot_mod(int a, int w, int n)
{
int pot, wyn, q;
// wykładnik w rozbieramy na sumę potęg 2
// przy pomocy algorytmu Hornera. Dla reszt
// niezerowych tworzymy iloczyn potęg a modulo n.
pot = a; wyn = 1;
for(q = w; q > 0; q /= 2)
{
if(q%2) wyn = (wyn*pot)%n;
pot = (pot*pot)%n; // kolejna potęga
}
return wyn;
}
// Procedura kodowania danych RSA
//-------------------------------
void kodowanie_RSA()
{
int e, n, t;
cout << "Kodowanie danych RSA\n"
"--------------------\n\n"
"Podaj wykladnik = "; cin >> e;
cout << " Podaj modul = "; cin >> n;
cout << "----------------------------------\n\n"
"Podaj kod RSA = "; cin >> t;
cout << "\nWynik kodowania = "
<< pot_mod(t, e, n) << endl;
czekaj();
}
// ********************
// ** Program główny **
// ********************
int main()
{
int w;
srand(time(NULL));
do
{
cout << "System szyfrowania danych RSA\n"
"-----------------------------\n"
" (C)2012 mgr Jerzy Walaszek\n\n"
"MENU\n"
"====\n"
"[0]-Koniec pracy programu\n"
"[1]-Generowanie kluczy RSA\n"
"[2]-Kodowanie RSA\n\n"
"Jaki jest twoj wybor? (0, 1 lub 2) : ";
cin >> w;
cout << "\n\n\n";
switch(w)
{
case 1 : klucze_RSA(); break;
case 2 : kodowanie_RSA(); break;
}
cout << "\n\n\n";
} while(w != 0);
return 0;
} |
Basic/'*******************************************************
** Przykładowa aplikacja obrazująca sposób działania **
** asymetrycznego systemu kodowania informacji RSA. **
** ------------------------------------------------- **
** (C)2020 mgr Jerzy Wałaszek **
** I Liceum Ogólnokształcące **
** im. Kazimierza Brodzińskiego **
** w Tarnowie **
******************************************************* '/
Declare Sub klucze_RSA()
Declare Sub kodowanie_RSA()
Dim w As Integer
Randomize
Do
Print "System szyfrowania danych RSA"
Print "-----------------------------"
Print " (C)2012 mgr Jerzy Walaszek "
Print
Print "MENU"
Print "===="
Print "[0]-Koniec pracy programu"
Print "[1]-Generowanie kluczy RSA"
Print "[2]-Kodowanie RSA"
Print
Input "Jaki jest twoj wybor? (0, 1 lub 2) : ", w
Print: Print: Print
If w = 1 Then
klucze_RSA()
Elseif w = 2 Then
kodowanie_RSA()
End If
Print: Print: Print
Loop Until w = 0
End
' Procedura oczekuje na naciśnięcie klawisza Enter
' po czym czyści ekran okna konsoli
'-------------------------------------------------
Sub Czekaj()
Print
Print "Zapisz te dane i nacisnij Enter"
Getkey
Cls
End Sub
' Funkcja obliczająca NWD dla dwóch liczb
'----------------------------------------
Function nwd(Byval a As Integer, _
Byval b As Integer) _
As Integer
Dim t As Integer
While b
t = b
b = a Mod b
a = t
Wend
nwd = a
End Function
' Funkcja obliczania odwrotności modulo n
'----------------------------------------
Function odwr_mod(Byval a As Integer, _
Byval b As Integer) _
As Integer
Dim As Integer u, w, x, z, q
u = 1: w = a
x = 0: z = b
While w
If w < z Then
q = u: u = x: x = q
q = w: w = z: z = q
End If
q = w\z
u = u-q*x
w = w-q*z
Wend
If x < 0 Then x += b
odwr_mod = x
End Function
' Procedura generowania kluczy RSA
'---------------------------------
Sub klucze_RSA()
Dim tp (9) As Integer_
= {11, 13, 17, 19, 23, 29, 31, 37, 41, 43}
Dim As Integer p, q, phi, n, e, d
Print "Generowanie kluczy RSA"
Print "----------------------"
Print
' generujemy dwie różne, losowe liczby pierwsze
Do
p = tp(Int(Rnd*10))
q = tp(Int(Rnd*10))
Loop Until p <> q
phi = (p-1)*(q-1)
n = p*q
' wyznaczamy wykładniki e i d
e = 3
While nwd(e, phi) <> 1
e += 2
Wend
d = odwr_mod(e, phi)
' gotowe, wypisujemy klucze
Print "KLUCZ PUBLICZNY"
Print "wykladnik e = ";e
Print " modul n = ";n
Print
Print "KLUCZ PRYWATNY"
Print "wykladnik d = ";d
Czekaj()
End Sub
' Funkcja oblicza modulo potęgę podanej liczby
'---------------------------------------------
Function pot_mod (Byval a As Integer, _
Byval w As Integer, _
Byval n As Integer) _
As Integer
Dim As Integer pot, wyn, q
' wykładnik w rozbieramy na sumę potęg 2. Dla reszt
' niezerowych tworzymy iloczyn potęg a modulo n.
pot = a: wyn = 1: q = w
While q > 0
if(q Mod 2) = 1 Then wyn = (wyn*pot) Mod n
pot = (pot*pot) Mod n ' kolejna potęga
q = q\2
Wend
pot_mod = wyn
End Function
' Procedura kodowania danych RSA
'-------------------------------
Sub kodowanie_RSA()
Dim As Integer e, n, t
Print "Kodowanie danych RSA"
Print "--------------------"
Print
Input "Podaj wykladnik = "; e
Input " Podaj modul = "; n
Print "----------------------------------"
Print
Input "Podaj kod RSA = "; t
Print
Print "Wynik kodowania = "; pot_mod(t, e, n)
Czekaj()
End Sub |
Python
(dodatek)# *******************************************************
# ** Przykładowa aplikacja obrazująca sposób działania **
# ** asymetrycznego systemu kodowania informacji RSA. **
# ** ------------------------------------------------- **
# ** (C)2024 mgr Jerzy Wałaszek **
# ** I Liceum Ogólnokształcące **
# ** im. Kazimierza Brodzińskiego **
# ** w Tarnowie **
# *******************************************************
import random
from os import system, name
# Funkcja czeka na dowolny klawisz i czyści ekran
# ------------------------------------------------
def czekaj():
print()
input("Zapisz te dane i naciśnij Enter")
if name == "nt":
_ = system("cls")
else:
_ = system("clear")
# Funkcja obliczająca NWD dla dwóch liczb
# ----------------------------------------
def nwd(a, b):
while b != 0:
t = b
b = a % b
a = t
return a
# Funkcja obliczania odwrotności modulo n
# ----------------------------------------
def odwr_mod(a, n):
p0 = 0
p1 = 1
a0 = a
n0 = n
q = n0 // a0
r = n0 % a0
while r > 0:
t = p0 - q * p1
if t >= 0:
t %= n
else:
t = n - ((-t) % n)
p0 = p1
p1 = t
n0 = a0
a0 = r
q = n0 // a0
r = n0 % a0
return p1
# Procedura generowania kluczy RSA
# ---------------------------------
def klucze_rsa():
tp = [11, 13, 17, 19, 23, 29, 31, 37, 41, 43]
print("Generowanie kluczy RSA")
print("----------------------")
print()
# generujemy dwie różne, losowe liczby pierwsze
while True:
p = tp[random.randrange(10)]
q = tp[random.randrange(10)]
if p != q: break
phi = (p - 1) * (q - 1)
n = p * q
# wyznaczamy wykładniki e i d
e = 3
while nwd(e, phi) != 1:
e += 2
d = odwr_mod(e, phi)
# gotowe, wypisujemy klucze
print("KLUCZ PUBLICZNY")
print("wykładnik e =", e)
print(" moduł n =", n)
print()
print("KLUCZ PRYWATNY")
print("wykładnik d =", d)
czekaj()
# Funkcja oblicza modulo potęgę podanej liczby
# ---------------------------------------------
def pot_mod(a, w, n):
# wykładnik w rozbieramy na sumę potęg 2
# przy pomocy algorytmu Hornera. Dla reszt
# niezerowych tworzymy iloczyn potęg a modulo n.
pot, wyn, q = a, 1, w
while q > 0:
if q % 2 != 0:
wyn = (wyn * pot) % n
pot = (pot * pot) % n # kolejna potęga
q //= 2
return wyn
# Procedura kodowania danych RSA
# -------------------------------
def kodowanie_rsa():
print("Kodowanie danych RSA")
print("--------------------")
print()
e = int(input("Podaj wykładnik = "))
n = int(input(" Podaj moduł = "))
print("----------------------------------")
print()
t = int(input("Podaj kod RSA = "))
print()
print("\nWynik kodowania =", pot_mod(t, e, n))
czekaj()
# ********************
# ** Program główny **
# ********************
while True:
print("System szyfrowania danych RSA")
print("-----------------------------")
print(" (C)2024 mgr Jerzy Wałaszek")
print()
print("MENU")
print("====")
print("[0]-Koniec pracy programu")
print("[1]-Generowanie kluczy RSA")
print("[2]-Kodowanie RSA")
print()
w = int(input("Jaki jest twój wybór? (0, 1 lub 2) : "))
print()
print()
print()
match w:
case 0:
break
case 1:
klucze_rsa()
case 2:
kodowanie_rsa()
print()
print()
print()
|
| Wynik: | ||||
|
| Instrukcja obsługi skryptu RSA | |
|---|---|
| Generacja kluczy | W pierwszej części formularza wygeneruj parę kluczy: publiczny i prywatny. Zachowaj je i wyczyść klucze, aby nikt nie mógł ich odczytać. |
| Szyfrowanie i Rozszyfrowywanie |
W drugiej części formularza wprowadź odpowiedni klucz (wykładnik oraz moduł), wiadomość (liczba < moduł) i kliknij przycisk "Koduj RSA". Wynik zostanie wyświetlony poniżej. |
JavaScript<html>
<head>
<title>
RSA
</title>
</head>
<body>
<div style="overflow-x: auto;"
align="center">
<table
border="0"
cellpadding="4"
style="border-collapse:
collapse" width="411">
<tr>
<td nowrap>
<form
name="frm"
style="text-align: center;
background-color:
#E7E7DA">
<b>
Generator kluczy RSA
</b><br/>
(C)2026 mgr
Jerzy Wałaszek
<br/><br/>
<input
onclick="js_genkeys();"
value="Generuj klucze"
type="button">
<input
onclick="js_keyclr();"
value="Czyść klucze"
type="button">
</span>
<div align="center">
<table
style="border-collapse:
collapse"
border="0"
cellSpacing="4"
cellPadding="4"
bgColor="#CCCCCC">
<tr>
<th
colSpan="2">
Klucz publiczny
</th>
<th
colSpan="2">
Klucz prywatny
</th>
</tr>
<tr>
<td valign="top">
wykładnik
</td>
<td
valign="top"
style="text-align:
center"
id="gkey_e">
.
</td>
<td
valign="top">
wykładnik
</td>
<td
valign="top"
style="text-align:
center"
id="gkey_d">
.
</td>
</tr>
<tr>
<td
valign="top">
moduł
</td>
<td
valign="top"
style="text-align:
center"
id="gkey_n1">
.
</td>
<td
valign="top">
moduł
</td>
<td
valign="top"
style="text-align:
center"
id="gkey_n2">
.
</td>
</tr>
</table>
</div>
<hr color="#FF0000">
<b>
Koder szyfru RSA
</b><br/>
(C)2026 mgr
Jerzy Wałaszek
<div align="center">
<table
style="border-collapse:
collapse"
border="0"
cellSpacing="4"
cellPadding="4"
bgColor="#CCCCCC">
<tr>
<td valign="top">
wykładnik
</td>
<td valign="top">
<input name="ed">
</td>
</tr>
<tr>
<td valign="top">
moduł
</td>
<td valign="top">
<input name="n">
</td>
</tr>
<tr>
<td valign="top">
wiadomość
</td>
<td valign="top">
<input name="m">
</td>
</tr>
</table>
</div>
<input
onclick="js_codeRSA();"
value="Koduj RSA"
type="button">
<input
onclick="js_codeclr();"
value="Czyść formularz"
type="button">
<br/>
<b>Wynik:</b>
<div id="out">.</div>
</form>
</td>
</tr>
</table>
</div>
<script language=javascript
type=text/javascript>
// Funkcja obliczająca NWD
// dla dwóch liczb
//------------------------
function nwd(a, b)
{
var t;
while(b != 0)
{
t = b;
b = a % b;
a = t;
};
return a;
}
// Funkcja obliczania odwrotności
// modulo n
//-------------------------------
function odwr_mod(a, n)
{
var a0,n0,p0,p1,q,r,t;
p0 = 0;
p1 = 1;
a0 = a;
n0 = n;
q = Math.floor(n0 / a0);
r = n0 % a0;
while(r>0)
{
t = p0 - q * p1;
if(t >= 0)
t = t % n;
else
t = n - ((-t) % n);
p0 = p1; p1 = t;
n0 = a0; a0 = r;
q = Math.floor(n0 / a0);
r = n0 % a0;
}
return p1;
}
// Funkcja generuje klucze RSA
//----------------------------
function js_genkeys( )
{
var tp = new Array
(11,13,17,19,23,29,31,37,
41,43);
var p,q,phi,n,e,d;
// generujemy dwie różne,
// losowe liczby pierwsze
do
{
p = tp[Math.floor(
Math.random() * 10)];
q = tp[Math.floor(
Math.random() * 10)];
}
while(p == q);
phi = (p - 1) * (q - 1);
n = p * q;
// wyznaczamy wykładniki e i d
for(e = 3;
nwd(e, phi) != 1;
e += 2);
d = odwr_mod(e, phi);
// gotowe, wypisujemy klucze
document.getElementById
("gkey_e").innerHTML = e;
document.getElementById
("gkey_d").innerHTML = d;
document.getElementById
("gkey_n1").innerHTML = n;
document.getElementById
("gkey_n2").innerHTML = n;
}
// Funkcja czyści wypisane dane
//-----------------------------
function js_keyclr()
{
document.getElementById
("gkey_e").innerHTML = " ";
document.getElementById
("gkey_d").innerHTML = " ";
document.getElementById
("gkey_n1").innerHTML = " ";
document.getElementById
("gkey_n2").innerHTML = " ";
}
// Funkcja oblicza modulo
// potęgę podanej liczby
//-----------------------
function pot_mod(a, w, n)
{
var pot,wyn,q;
// wykładnik w rozbieramy na sumę
// potęg 2 przy pomocy algorytmu
// Hornera. Dla reszt niezerowych
// tworzymy iloczyn potęg
// a modulo n
pot = a;
wyn = 1;
for(q = w;
q > 0;
q = Math.floor(q / 2))
{
if(q % 2)
wyn = (wyn * pot) % n;
// kolejna potęga
pot = (pot * pot) % n;
};
return wyn;
}
// Kodowanie RSA
//--------------
function js_codeRSA()
{
var e,n,t,s;
e = parseInt(document
.frm.ed.value);
n = parseInt(document
.frm.n.value);
t = parseInt(document
.frm.m.value);
if(isNaN(e) ||
isNaN(n) ||
isNaN(t))
s = "Błąd danych";
else
s = pot_mod(t, e, n);
document.getElementById
("out").innerHTML = s;
}
function js_codeclr()
{
document.frm.ed.value = "";
document.frm.n.value = "";
document.frm.m.value = "";
document.getElementById
("out").innerHTML = " ";
}
</script>
</body>
</html>
|
Sieć komputerowa Internet jest środowiskiem o niskim bezpieczeństwie poufności przesyłanych danych. Pakiety danych podróżujące pomiędzy różnymi węzłami sieci mogą być podglądane przez osoby nieupoważnione. Szyfrowanie danych zapewni nam bezpieczeństwo. Nawiązanie bezpiecznego połączenia wykorzystującego szyfrowanie RSA składa się z następujących etapów:
Bezpieczne połączenia internetowe są dzisiaj szeroko wykorzystywane w sieci do prowadzenia działalności handlowej. Dzięki nim klienci banków mogą bezpiecznie zarządzać swoimi kontami oraz dokonywać zakupów w sieci z wykorzystaniem kart płatniczych.
![]() |
Zespół Przedmiotowy Chemii-Fizyki-Informatyki w I Liceum Ogólnokształcącym im. Kazimierza Brodzińskiego w Tarnowie ul. Piłsudskiego 4 ©2026 mgr Jerzy Wałaszek |
Materiały tylko do użytku dydaktycznego. Ich kopiowanie i powielanie jest dozwolone pod warunkiem podania źródła oraz niepobierania za to pieniędzy.
Pytania proszę przesyłać na adres email:
Serwis wykorzystuje pliki cookies. Jeśli nie chcesz ich otrzymywać, zablokuj je w swojej przeglądarce.
Informacje dodatkowe.