Šifrovanie pomocou XOR

Václav Antošík       14.05.2008       VB.NET, Algoritmy       14068 zobrazení

Článok ukazuje, ako pracovať s logickou operáciou XOR a prácu s rôznymi číselnými sústavami.

Úvod

V tomto článku sa pokúsim názorne ukázať a vysvetliť, ako si spraviť vlastnú aplikáciu pre šifrovanie textu pomocou logickej operácie XOR. Nepoužijeme však štandardný operátor Visual Basicu, ale pokúsime sa napísať si vlastnú triedu, ktorá nám poslúži ako náhrada. Budeme v nej prevádzať čísla z desiatkovej sústavy do dvojkovej a opačne a potom sa pokúsime medzi číslami v dvojkovej sústave vyrátať XOR. Výsledkom bude zašifrovaný text v binárnej forme.

 

Design

Na úvod si vytvoríme „čistú“ application vo Visual Studiu. Na formulár si natiahneme dva RichTextBoxi jeden TextBox a dve tlačítka. Tlačítkam zmeníme meno na ButtR a ButtS. TextBox nazveme Pass a RichTextBoxi TB a TB2. Náš formulár by mal teraz vypadať približne ako tento na obrázku. (Samozrejme, môžete si pridať aj popisky a iné „ozdôbky“). Teraz sa vrhneme na nastavovanie vlastností našich nových objektov. Ako prvé zmeníme properties „Text“ tlačítok na „Rozšifruj“ a tlačítka s menom ButtS na „Šifruj“. Potom ešte nastavíme vlastnosť TextBoxu „PasswordChar“ na „*” a sme v designéry hotoví.

  design

Trochu teórie

Pred písaním kódu by sa asi na úvod hodilo trošku teórie. V princípe užívateľ zadá do prvého RichTextBoxu text, ktorý chce zakódovať. Do TextBoxu zadá heslo „neobmedzenej“ dĺžky. Po stlačení tlačítka Šifruj teda program prevedie každý znak hesla do dvojkovej sústavy a každý znak si uloží v dvojkovej sústave do jednej položky v poli. Potom začne prechádzať text určený na zašifrovanie a každý znak tohto textu prevedie tiež do dvojkovej sústavy a spraví postupne logickú operáciu XOR medzi týmto znakom a jednotlivými znakmi z poľa(znaky hesla prevedené do dvojkovej sústavy) v presnom poradí od nultej položky poľa po dĺžku poľa. Takto prejde celý text a výsledok nakoniec zobrazí. V tomto momente užívateľ vidí svoj zašifrovaný text v binárnej forme (viď. obr.) Tento text môže napríklad poslať niekomu „bezpečne“ cez internet a nikto, kto nemá heslo, v najlepšom prípade J text nerozšifruje. Adresát si potom otvorí našu aplikáciu a do prvého RichTextBoxu si nahrá daný zašifrovaný text. Potom napíše do TextBoxu správne heslo a stlačí tlačítko Rozšifrovať. Program prevedie heslo znova na pole, v ktorom každý prvok bude reprezentovať binárnu podobu jedného znaku hesla. Potom bude čítať zašifrovaný text po ôsmich bitoch a preklápať ho cez operáciu XOR na text už užívateľovi čitateľný.

 

XOR

Logická operácia XOR(exclusive or) je binárna logická operácia. Pravdivostná hodnota je jedna práve vtedy , keď práve jeden z argumentov je jedna. Viď. obrázok.

xorTable

 

To2Base

Ďalej budeme potrebovať preložiť číslo z desiatkovej sústavy do dvojkovej. Na to nám poslúži jednoduchý algoritmus. Číslo v desiatkovej sústave predelíme dvojkou a zapamätáme si zvyšok po delení. Celočíselný výsledok znovu predelíme dvojkou, a tak to spravíme osemkrát a výsledkom je krásnych osem bitov, čiže jeden byte z daného znaku.

 

To10Base

Prevod z dvojkovej sústavy do desiatkovej je o niečo zaujímavejší. Pozrieme sa na jeden byte v dvojkovej sústave. Pôjdeme sprava. Ak je prvým číslom jednotka, tak počítame dva na nultú krát jedna a ak je tam nula, tak počítame dva na nultú krát nula potom dáme plus a počítame ďalšie miesto podobne. Ak je tam jednotka, tak dva na prvú krát jedna alebo ak je tam nula, tak krát nula. Takto pokračujeme, pokiaľ nedosiahneme posledného bitu. Hodnota výsledného súčtu je číslo prevedené do desiatkovej sústavy.

 

Viac informácií a podrobnejší popis prevodu sústav môžete nájsť na adresách :

 http://sk.wikipedia.org/wiki/Dvojkov%C3%A1_%C4%8D%C3%ADseln%C3%A1_s%C3%BAstava

 http://www.spsest.sk/~peter/eps/reprezentaciaCiselnychUdajov/ciselneSustavy.html

 

Píšeme kód

 

Trieda MyXor

Teraz, keď už máme približný teoretický základ, môžeme sa pustiť do písania samotného kódu aplikácie. Ako prvú si vytvoríme triedu, ktorá nám vypočíta XOR a prevedie čísla do požadovaných sústav. Jadrom tejto triedy bude verejná funkcia DoXor. V prvom argumente príde znak hesla, vo forme reťazca a tento reťazec bude obsahovať hodnotu znaku, prevedenú do dvojkovej sústavy. Prakticky tam potom bude 8 čísel.(Buď 1 alebo 0). V druhom parametri dostaneme pole znakov hesla v rovnakom formáte ako pri firstBits. Takto vyzbrojený postupne „počítame“ XOR medzi znakom firstBits a znakmi hesla secondBits. Výsledok bude zašifrovaný byte v binárnej forme.

     ''' <summary>
''' Jadro nasej triedy. Tato funkcia prevadza bity pomocou logickej operacie XOR
''' </summary>
''' <param name="firstBits"></param>
''' <param name="secondBits"></param>
''' <returns></returns>
''' <remarks></remarks>
Public Function DoXor(ByVal firstBits As String, ByVal secondBits() As String) As String
Dim resoult As String = String.Empty
For j As Integer = 0 To secondBits.GetUpperBound(0)
For i As Integer = 0 To 7
If firstBits.Chars(i) = "0" And secondBits(j).Chars(i) = "0" Then resoult &= "0"
If firstBits.Chars(i) = "0" And secondBits(j).Chars(i) = "1" Then resoult &= "1"
If firstBits.Chars(i) = "1" And secondBits(j).Chars(i) = "0" Then resoult &= "1"
If firstBits.Chars(i) = "1" And secondBits(j).Chars(i) = "1" Then resoult &= "0"
Next i
firstBits = resoult
If j < secondBits.GetUpperBound(0) Then resoult = String.Empty
Next j
Return resoult
End Function

Funkcia na prevod čísla z desiatkovej sústavy do dvojkovej sa volá To2Base a jej popis je nasledovný:

     ''' <summary>
''' Funkcia prevadza cislo z desiatkovej sustavy do dvojkovej
''' a vracia vysledok vo forme retazca obsahujuceho vysledne bity
''' </summary>
''' <param name="number">Cislo, ktore bude prevedene na retazec</param>
''' <returns></returns>
''' <remarks></remarks>
Public Function To2Base(ByVal number As Byte) As String
Dim resoult As String = String.Empty
For i = 0 To 7
resoult &=
CStr(number Mod 2)
number =
CByte(number \ 2)
Next
Return Reverse(resoult)
End Function

Ako vidieť zo zápisu, delí sa postupne číslo v desiatkovej sústave číslom dva a zvyšky po delení sa ukladajú do premennej resoult. Číslo number sa zmenší o polovicu. Operátor „\“ vyjadruje celočíselné delenie a operátor Mod vyjadruje zvyšok po delení daným číslom. Nakoniec funkcia jednotlivé bity v reťazci prehodí. Prvý bude posledný a posledný bude prvý atď.

 

Funkcia, ktorá nám to prehodí späť do desiatkovej sústavy, vypadá takto:

     ''' <summary>
''' Funkcia prevadza cislo z dvojkovej sustavy do desiatkovej
''' </summary>
''' <param name="number">Retazec obsahujuci bity prevadzaneho bytu</param>
''' <returns>Cislo v desiatkovej sustave</returns>
''' <remarks></remarks>
Public Function To10Base(ByVal number As String) As Byte
Dim resoult As Byte
For i As Integer = 7 To 0 Step -1
If number.Chars(i) = "1" Then resoult += CByte(2 ^ (7 - i))
Next
Return resoult
End Function

Keď narazíme v byte na jednotku, prirátame k výsledku hodnotu podľa toho, na ktorej pozícií sa v byte nachádza. V princípe je to mocnina, ktorej veľkosť je závislá na pozícií v byte čísla dva.

 

Formulár

Teraz, keď už máme triedu napísanú, pokúsime sa ju použiť v našom formulári. Prepneme sa do designéra a dvakrát klikneme na tlačítko Šifrovať. Potom doplníme nasledujúci kód.

     Private Sub ButtS_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ButtS.Click
If Not Pass.Text = String.Empty Then
Dim acc As New MyXor 'Vytvorime novu instanciu triedy MyXor
Dim buff As String = String.Empty 'Vytvorime pomocnu premennu typu text
Dim passArr(Pass.Text.Length - 1) As String 'A pole typu text
ButtS.Enabled = False 'Tlacitko pre sifrovanie zakazeme pouzit
ButtR.Enabled = True 'Tlacitko pre desifrovanie dovolime pouzit
'V tomto cykle budeme prechadzat text hesla urceny na zasifrovanie
'Kazdy taky znak prevedieme do dvojkovej sustavy pomocou
'funkcie To2Base a ulozime ho do jedneho prvku pola
For i As Integer = 0 To Pass.Text.Length - 1
'Testujem ci sa znak zmesti do jedneho bytu
If Convert.ToInt32(Pass.Text.Chars(i)) < 255 Then
passArr(i) = acc.To2Base(Convert.ToByte(Pass.Text.Chars(i)))
Else
'Ak nie tak pouzijem zastupny znak "."
passArr(i) = acc.To2Base(Convert.ToByte(46))
End If
Next
'Tento cyklus prechadza textbox s textom urcenym na zasiforvanie
'znak po znaku. Kazdy znak prevedie do dvojkovej sustavy kde prechadza
'cez operaciu XOR s kazdym znakom hesla.
For i As Integer = 0 To Tb.Text.Length - 1
'Testujem ci sa znak zmesti do jedneho bytu
If Convert.ToInt32(Tb.Text.Chars(i)) < 255 Then
buff &= acc.DoXor(acc.To2Base(Convert.ToByte(Tb.Text.Chars(i))), passArr)
Else
'Ak nie tak pouzijem zastupny znak "."
buff &= acc.DoXor(acc.To2Base(46), passArr)
End If
Next
'Vysledok sifrovania nakoniec zobrazime v RichTextBoxe Tb
Tb.Text = buff
Else
MsgBox("Vyplnte prosím pred šifrovaním heslo", MsgBoxStyle.Information, "Pozor")
End If
End Sub

Na začiatku skontrolujeme, či užívateľ zadal pred šifrovaním heslo. Ak nie, tak vypíšeme hlášku s upozornením. Po tom, ako užívateľ stlačí tlačítko šifrovať, program toto tlačítko vyšedí a aktivuje tlačítko „rozšifrovať“. Potom sa už vrhne na samotné šifrovanie. Každý znak hesla prevedieme do dvojkovej sústavy a uložíme ho ako jeden prvok poľa passArr. Potom budeme prechádzať text určený na zašifrovanie a prevádzať každý znak do dvojkovej sústavy a šifrovať pomocou funkcie DoXor. Výsledok šifrovania si ukladáme do pomocnej premennej buff a nakoniec zobrazíme do RichTextBoxu s „name“ Tb. Na predchádzajúcom kóde je ešte zaujímavý prevod znaku na číslo. Toto dosiahneme použítím Convert.ToByte. Táto funkcia nám poslúži na prevedenie znaku na číslo v desiatkovej sústave. Aby sme si to zjednodušili, pridáme podmienku, ktorá nám vyfiltruje len znaky s číslom od 0 po 255(rozsah 0-255 je interval, z ktorého sme schopní uložiť každé číslo práve do jedného bytu). Vyhneme sa tým nutnosti kódovať jeden znak do viacerých bytov. Avšak potom musíme brať do úvahy fakt, že nie každé písmeno patrí do intervalu od 0-255(sú to hlavne špeciálne znaky a znaky s diakritikou). Preto ak nájdeme znak, ktorý nie sme schopní previesť do jedného bytu, prevedieme ho na znak „.“

 

Prejdime znovu do designéra a kliknime dvakrát na tlačítko „Rozšifrovať“. Pridáme nasledujúci kód.

     Private Sub ButtR_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ButtR.Click
Dim acc As New MyXor 'Vytvorime novu instanciu triedy MyXor
Dim buff As String = Tb.Text 'Nahrame si sifrovany text do premennej
Dim passArr(Pass.Text.Length - 1) As String 'A pole typu text
'Znova prevedieme heslo do dvojkovej sustavy a ulozime si ho do pola
For i As Integer = Pass.Text.Length - 1 To 0 Step -1
passArr(i) = acc.To2Base(Convert.ToByte(Pass.Text.Chars(i)))
Next
Tb2.Text = String.Empty 'Premazeme RichTextBox urceny pre zobrazenie vysledku
'V cykle prejdeme cely zasifrovany text tak, ze citame po skupinach 8 bitov.
'Kazdych 8 bitov prezenieme cez operacu XOR spolu s bitmi hesla
'Vysledok XORu potom prevedieme do 10tkovej sustavy a prevedieme na znak
For i As Integer = 0 To buff.Length - 1 Step 8
Tb2.Text &= Convert.ToChar(acc.To10Base(acc.DoXor(buff.Substring(i, 8), passArr)))
Next
End Sub

Tento kus kódu robí v podstate to isté ako šifrovanie, len obrátene. Zaujímavé je, že číslo v dvojkovej sústave, čo vypadne z funkcie DoXor, prevedieme do desiatkovej sústavy a potom pomocou Convert.ToChar na znak, ktorý zobrazíme v RichTextBoxe.

 

Záver

Naša aplikácia je hotová a pripravená na testovanie. Určite je na nej ešte čo vylepšovať, ponúka sa viacero možností. Hodilo by sa dopísať funkciu pre šifrovanie tak, aby vedela pracovať aj so znakmi väčšími ako jeden byte. No nechám to už na čitateľa, nech experimentuje. Tento článok vznikol v slnkom zaliatej bratislavskej medickej záhrade a dúfam, že pomôže programovaniachtivým čitateľom.

 

Všetky konštruktívne návrhy, otázky a opravy sú vítané.

 

Zdrojový kód :

 

hodnocení článku

1 bodů / 1 hlasů       Hodnotit mohou jen registrované uživatelé.

 

Mohlo by vás také zajímat

Tipy a triky pro ASP.NET - díl 5.: Komponenta pro zadávání data a času

V tomto díle se podíváme na to, jak s využitím komponenty CalendarExtender z knihovny AjaxControlToolkit napsat komponentu pro snadné zadávání data, která podporuje validaci a datové zdroje.

Windows Presentation Foundation (WPF) - díl 5.: Device independent pixels

Co je to DPI a proč by vás to mělo zajímat? Jak se aplikují automatické transformace při změně této hodnoty? Článek je prvním pohledem tohoto seriálu do transformací a pozičního systému WPF.

Práce s časovými pásmy a letním časem v aplikaci a databázi - díl 3.: DateTimeOffset v .NET Frameworku

DateTimeOffset je méně využívanou alternativou struktury DateTime v .NET Frameworku. Navíc dovoluje ukládat časové pásmo a pohodlně s ním pracovat.

 

 

Nový příspěvek

 

Mr.

1'

csharp|

xml|

css|


'

nahlásit spamnahlásit spam -1 / 1 odpovědětodpovědět

Diskuse: Šifrovanie pomocou XOR

Když uživatel použije heslo obsahující numerické znaky (já použil '123pwd') a při dekódování čísla v hesle prohází, dojde k správnému rozšifrování ('321pwd').

nahlásit spamnahlásit spam 4 / 6 odpovědětodpovědět

Fúha, tak teraz ste ma dostali :-). No máte pravdu. Totiž nezáleží na tom v akom poradí sa počíta XOR medzi zašifrovaným bytom a bytmi hesla. Preto je jedno, či zadáme ako heslo "abc" alebo "bca" atp. Riešenie tohto problému si môžte spraviť ako samostatnú úlohu ;-). Ďakujem za pripomienku.

Vašo.

nahlásit spamnahlásit spam 0 / 2 odpovědětodpovědět

Já bych do toho řetězce který chcem zakódovat vložil na začátek heslo a pak zakódoval. Při rozkódování by si to ověřilo jestli je heslo a začátek rozkodovaného řetězce shodný, pokud by byl, heslo bych z výsledného textu odstranil, pokud ne napsalo by to "špatné heslo".

nahlásit spamnahlásit spam 0 / 2 odpovědětodpovědět
                       
Nadpis:
Antispam: Komu se občas házejí perly?
Příspěvek bude publikován pod identitou   anonym.

Nyní zakládáte pod článkem nové diskusní vlákno.
Pokud chcete reagovat na jiný příspěvek, klikněte na tlačítko "Odpovědět" u některého diskusního příspěvku.

Nyní odpovídáte na příspěvek pod článkem. Nebo chcete raději založit nové vlákno?

 

  • Administrátoři si vyhrazují právo komentáře upravovat či mazat bez udání důvodu.
    Mazány budou zejména komentáře obsahující vulgarity nebo porušující pravidla publikování.
  • Pokud nejste zaregistrováni, Vaše IP adresa bude zveřejněna. Pokud s tímto nesouhlasíte, příspěvek neodesílejte.

přihlásit pomocí externího účtu

přihlásit pomocí jména a hesla

Uživatel:
Heslo:

zapomenuté heslo

 

založit nový uživatelský účet

zaregistrujte se

 
zavřít

Nahlásit spam

Opravdu chcete tento příspěvek nahlásit pro porušování pravidel fóra?

Nahlásit Zrušit

Chyba

zavřít

feedback