Mateusz Mazurek – programista z pasją

Blog o Pythonie i kilku innych technologiach. Od developera dla wszystkich.

AlgorytmikaProgramowanie

Algorytm kryptograficzny XOR – Java

Dziś od strony bezpieczeństwa.. :)
Algorytm XOR nie jest może najbezpieczniejszym algorytmem szyfrującym na świecie (przy krótkich hasłach jest mocno kiepski), ale jest prosty i nadal stanowi podstawę bardziej złożonych algorytmów takich jak np. DES. Przy spełnieniu pewnych warunków poziom bezpieczeństwa oferowany przez ten algorytm dość szybko wzrasta.
Inne nazwy to alternatywa wykluczająca czy binarne sumowanie mod 2.
Jest on tzw. szyfrem strumieniowym – czyli szyfruje każdy bit szyfrowanego tekstu.

Pierwszym krokiem algorytmu jest zamiana tekstu który szyfrujemy na odpowiednik binarny. Tworzymy z każdej litery 8 bitowe słowo binarne, zamieniając wartość litery (kod ASCII) i odpowiednio rozszerzając powstałą liczbę dwójkową.
Podobnie robimy z kluczem, czyli tekstem który będzie nam potrzeby do zaszyfrowania jak i odszyfrowania tekstu.
Co ważne, aby zaszyforwać tekst i aby go odszyfrować używać będziemy dokładnie tej samej procedury, tylko z innymi parametrami wejściowymi, ponieważ:

 a \oplus b = c [math]
c \oplus b = a[/math]

Gdzie a to nasz tekst do zaszyfrowania, b jest kluczem, a c zaszyfrowanym tekstem. Jak widzimy szyfrując zaszyfrowany tekst tym samym kluczem – odszyfrowywujemy go.
Co jest genialną właściwością.

Tablica prawdy dla XOR wygląda następująco:

a | b | w
0 | 0 | 0
0 | 1 | 1
1 | 1 | 0
1 | 0 | 1

Przejdźmy ten algorytm. Zakładam że umiesz przeliczać liczby w systemie dziesiętnym na binarny, dlatego nie użyję konkretnych słów a przykładowych ciągów zer i jedynek.

Tekst do zaszyfrowania:
0 1 0 0 0 0 1 1 1 0 1 0

Klucz:
1 1 0 1 1

Szyfrujemy:
(klucz powielamy tyle ile potrzeba)

0 1 0 0 0 0 1 1 1 0 1 0 tekst
1 1 0 1 1 1 1 0 1 1 1 1 klucz
1 0 0 1 1 1 0 1 0 1 0 1 zaszyfrowany tekst

No i teraz odszyfrujemy go :)

1 0 0 1 1 1 0 1 0 1 0 1 zaszyfrowany tekst
1 1 0 1 1 1 1 0 1 1 1 1 klucz ten sam co poprzednio
0 1 0 0 0 0 1 1 1 0 1 0 odszyfrowany tekst

Jak widać odszyfrowany tekst jest taki sam ten który chcieliśmy zaszyfrować.

Oczywiście tekst po zaszyfrowaniu będzie wyglądał conajmniej dziwnie. Ale powoli, zobaczmy na implementacje tego w Javie

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
publicclass krypto {
   

    String haslo_bin;// haslo w postaci binarnej
   
    String do_szyfrowania;//txt w postaci binarnej
   
    privateString DectoBin(int a)
    {
       
        StringBuilder t =new StringBuilder(Integer.toBinaryString(a));//przeliczam
        int l = t.length();
        if(l<8)
        {
            for(int i=l;i<8;i++)
                t.insert(0, "0");//rozszerzam do 8 bitow
        }
    return t.toString();//zwracam
   
    }

    public krypto(String h, String haslo)
    {
    //konstruktor
    StringBuilder t =new StringBuilder();
       
    for(int i=0;i<haslo.length();i++)
        t.append(DectoBin((int)haslo.charAt(i)*2));
       
    haslo_bin=t.toString();
    StringBuilder hh =new StringBuilder();
       
    for(int i=0;i<h.length();i++)
        hh.append(DectoBin((int)h.charAt(i)));    
    do_szyfrowania=hh.toString();
//tworze w konstruktorze calosc hasla i txt do zaszyforwania
    }
   
   
    publicString Go()
    {
   
        StringBuilder w =new StringBuilder();
        for(int i=0,j=0;i<do_szyfrowania.length();i++,j++){
       
            {
            if(j==haslo_bin.length()) j=0;  
            boolean a =(do_szyfrowania.charAt(i)=='1'&& haslo_bin.charAt(j)=='1')||(do_szyfrowania.charAt(i)=='0'&& haslo_bin.charAt(j)=='0')?true:false;
            w.append(a==true?"0":"1");
              //szyfruje, tworze ciag zer i jedynek juz zaszyfrowany
            }
       
       
        }
       
    return w.toString();//zwracam zera i jedynki
    }
   
   
    return wynik;
    }
   
    publicstaticString toText(String a){
   
    String tt="";
    String wynik="";
     
    for(int i=0;i<a.length();i++)
    {
   
        tt=tt.concat(Character.toString(a.charAt(i)));
            if(tt.length()==8)//dziele wynik co 8
            {
         
                wynik=wynik.concat(Character.toString((char)((Integer.parseInt(tt, 2)))));    
                //po jednej literce przetwarzam na tekst
                tt="";
   
            }
       
    }
   
    return wynik;//i zwracam.
    }
   
   
}

No i wywołanie:

1
2
3
4
  publicstaticvoid main(String[] args){
     krypto t =new krypto("Programowanie jest ciekawe!", "nasz klucz",1);
     System.out.println(t.toText(t.Go()));
    }

No i w taki sposób tekst „Programowanie jest ciekawe!”, używając klucza „nasz klucz” będzie wyglądał tak:

Œ°‰“2·µ ±•²«ƒÔ*³«žæ—µ§•7³ù

:)

Pozdrawiam!

Dzięki za wizytę,
Mateusz Mazurek

A może wolisz nowości na mail?

Subskrybuj
Powiadom o
guest

Witryna wykorzystuje Akismet, aby ograniczyć spam. Dowiedz się więcej jak przetwarzane są dane komentarzy.

0 komentarzy
Inline Feedbacks
View all comments