Sunteți pe pagina 1din 10

Ministerul Educaiei al Republicii Moldova Universitatea Tehnic a Moldovei Facultatea Calculatoare Informatic i Microelectronic Catedra Automatica i Tehnologii Informaionale

Disciplina: Securitatea informaiei i protocoale de comunicaie

RAPORT Lucrare de laborator Nr.5 Tema: Algoritmi simetrici de criptare. Algoritmul DES.

A efectuat :

studentul grupei TI-101 Dovgaliuc Victor

A verificat:

lector superior Bulai Rodica

Chiinu 2012

Scopul lucrrii De implimentat algoritmul de criptare DES. Sarcina lucrarii De realizat un program care ar implementa funcionarea algoritmului DES.

Noiuni teoretice despre algoritmul DES Standardul de Criptare a Datelor (n englez Data Encryption Standard, DES) este un cifru (o metod de criptare a informaiei), selectat ca standard federal de procesare a informaiilor n Statele Unite n 1976, i care s-a bucurat ulterior de o larg utilizare pe plan internaional. Algoritmul a fost controversat iniial, avnd elemente secrete, lungimea cheii scurt i fiind bnuit c ascunde de fapt o porti pentru NSA. DES a fost analizat intens de ctre profesionaliti n domeniu i a motivat nelegerea cifrurilor bloc i criptanaliza lor. DES este astzi considerat nesigur pentru multe aplicaii. Acest lucru se datoreaz n principiu cheii de 56 de bii, considerat prea scurt; cheile DES au fost sparte n mai puin de 24 de ore. De asemenea, exist unele rezultate analitice care demonstreaz slbiciunile teoretice ale cifrului, dei nu este fezabil aplicarea lor. Se crede c algoritmul este practic sigur n forma Triplu DES, dei exist atacuri teoretice i asupra acestuia. n ultimii ani, cifrul a fost nlocuit de Advanced Encryption Standard (AES). n unele documentaii, se face distincie ntre DES ca standard i algoritmul de la baza lui, numit DEA (Algoritmul de Criptare a Datelor - n englez, Data Encryption Algorithm). 2 2.1 Descriere DES este cifrul bloc arhetip un algoritm care ia un ir de lungime fix de bii de text normal i l transform print-o serie de operaii complexe ntr-un ir de bii criptai de aceeai lungime. n cazul DES, mrimea blocului este de 64 bii. DES folosete de asemenea i o cheie pentru particularizarea transformrii, astfel nct numai cei care cunosc cheia folosit s poat efectua decriptarea. Cheia este format din 64 de bii; totui, numai 56 dintre ei sunt folosii propriu-zis de algoritm. Opti bii sunt utilizai ca bii de paritate i nu sunt necesari dup acest test. Deci cheia efectiv are doar 56 de bii, i aa este citat de obicei. Ca i alte cifruri bloc, DES nu este o cale sigur de criptare folosit de sine-stttor. El trebuie folosit ntr-un mod de operare. FIPS-81 specific cteva feluri pentru utilizarea cu DES. Alte comentarii despre acest lucru apar n FIPS-74. Structura general Structura general a algoritmului: sunt 16 pai identici de procesare, numii runde. Exist i cte o permutare iniial i final, numite PI and PF, care sunt funcii inverse (PI "anuleaz" aciunea lui PF i vice versa). PI i PF nu au aproape nici o importan criptografic, dar au fost incluse pentru a facilita ncrcarea i descrcarea blocurilor folosind hardware-ul din anii 1970. naintea rundelor principale, blocul este mprit n dou jumti, de cte 32 de bii, i procesate alternativ; aceast alternare este cunoscut drept Schema Feistel. Structura Feistel asigur c criptarea i decriptarea sunt procese foarte asemntoare singura dieferen este ordinea aplicrii subcheilor invers la decriptare. Restul algoritmului este identic. Acest lucru simplific implementarea, n special cea hardware, deoarece nu e nevoie de algoritmi separai. Funcia F amestec jumtate din bloc cu o subcheie. Rezultatului funciei F este combinat cu cealalt jumtate de bloc, iar jumtile sunt interschimbate naintea urmtoarei runde. Dup ultima rund, jumtile nu sunt schimbate; aceasta este o trstur a structurii Feistel care face din criptare i decriptare procese similare. 2.2 2

Reazilarea sarcinii Pentru implementarea algoritmului DES a fost ales limbajul de programare C# i IDE Visual Studio 2010.
using using using using using System; System.Collections.Generic; System.Linq; System.Text; System.Collections;

namespace lab5DES { class AlgDES { int[] IP = { 58, 50, 42, 34, 26, 18, 10, 2, 60, 52, 44, 36, 28, 20, 12, 4, 62, 54, 46, 38, 30, 22, 14, 6, 64, 56, 48, 40, 32, 24, 16, 8, 57, 49, 41, 33, 25, 17, 9, 1, 59, 51, 43, 35, 27, 19, 11, 3, 61, 53, 45, 37, 29, 21, 13, 5, 63, 55, 47, 39, 31, 23, 15, 7 }; int[] FP = { 40, 8, 48, 16, 56, 24, 64, 32, 39, 7, 47, 15, 55, 23, 63, 31, 38, 6, 46, 14, 54, 22, 62, 30, 37, 5, 45, 13, 53, 21, 61, 29, 36, 4, 44, 12, 52, 20, 60, 28, 35, 3, 43, 11, 51, 19, 59, 27, 34, 2, 42, 10, 50, 18, 58, 26, 33, 1, 41, 9, 49, 17, 57, 25 }; int[] Ext = { 32, 1, 2, 3, 4, 5, 4, 5, 6, 8, 9, 10, 12, 13, 14, 16, 17, 18, 20, 21, 22, 24, 25, 26, 28, 29, 30, 7, 11, 15, 19, 23, 27, 31, 17, 26, 10, 14, 9, 6, 25 8, 12, 16, 20, 24, 28, 32, 9, 13, 17, 21, 25, 29, 1

int[] P =

}; 16,

7, 20, 21, 29, 12, 28, 1, 15, 23, 5, 18, 31, 2, 8, 24, 32, 27, 3, 19, 13, 30, 22, 11, 4,

}; int[,] S1 = { {14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7}, {0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8}, {4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0}, {15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13}}; int[,] S2 = { {15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10}, {3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5}, {0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15}, {13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9}}; int[,] S3 = { {10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8}, {13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1}, {13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7}, {1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12} }; int[,] S4 = { {7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15}, {13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9}, {10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4}, {3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14} }; int[,] S5 = { {2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9}, {14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6}, {4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14}, {11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3}

}; int[,] S6 = { {12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11}, {10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8}, {9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6}, {4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13} }; int[,] S7 = { {4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1}, {13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6}, {1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2}, {6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12} }; int[,] S8 = { {13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7}, {1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2}, {7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8}, {2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11} }; int[] PC1 = { 57, 49, 41, 1, 58, 10, 2, 19, 11, 63, 55, 7, 62, 14, 6, 21, 13, }; int[] PC2 = { 14, 3, 23, 16, 41, 30, 44, 46, int[] Rot = { }; 1, 1, 17, 28, 19, 7, 52, 40, 49, 42, 11, 15, 12, 27, 31, 51, 39, 50, 24, 6, 4, 20, 37, 45, 56, 36, 1, 21, 26, 13, 47, 33, 34, 29, 1 5, 10, 8, 2, 55, 48, 53, 32 33, 50, 59, 3, 47, 54, 61, 5, 25, 42, 51, 60, 39, 46, 53, 28, 17, 34, 43, 52, 31, 38, 45, 20, 9, 26, 35, 44, 23, 30, 37, 12, 18, 27, 36, 15, 22, 29, 4

2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2,

}; //Functia Sau - exclusiv pentru 2 secvente binare public char[] XOR(char[] a, char[] b) { char[] result = new char[a.Length]; for(int i = 0 ; i < a.Length; i++) { if(a[i] == b[i]){ result[i] = '0'; }else { result[i] = '1'; } } return result; } //Transformarea a 8 secvente binare cite 6 biti in public string B6toB4(char[] B, int nr) { int a = 0; int b = 0; int b4 = 0; int[] iB = new int[6]; for (int i = 0; i < 6; i++) { if (B[i] == '1') { iB[i] = 1; } else { iB[i] = 0; } } string sb4 = string.Empty;

4 biti

a = (iB[0] * 2) + iB[5];//aflam numarul intreg din bitul 1 si 6 b = (iB[1] * 8) + (iB[2] * 4) + (iB[3] * 2) + iB[4]; // aflam numarul intreg din bitii 2,3,4,5 // gasim valiarea corespunzatoare din tabelele Si[a,b] switch (nr) {

case case case case case case case case

0: 1: 2: 3: 4: 5: 6: 7:

b4 b4 b4 b4 b4 b4 b4 b4

= = = = = = = =

S1[a, S2[a, S3[a, S4[a, S5[a, S6[a, S7[a, S8[a,

b]; b]; b]; b]; b]; b]; b]; b];

break; break; break; break; break; break; break; break;

} //Transformarea din valoare zecimal[ ]n binar[ if (b4 < 8 && b4 > 3) { sb4 = "0"; } else if (b4 == 0 || b4 == 1) { sb4 = "000"; } else if (b4 < 4 && b4 > 1 ) {sb4 = "00";} sb4 += Convert.ToString(b4, 2); return sb4; // returnam sir de secvente binare a cite 4 biti } // functia F public char[] F(char[] Keyi, char[] Ri) { char[] RiExt = new char[48]; char[] B = new char[48]; char[,] bTable = new char[8, 6]; // B = E(Ri) XOR Ki string b4 = string.Empty; char[] b6 = new char[6]; char[] cb4 = new char[32]; char[] Pb4 = new char[32]; int count = 0; //Extention Ri pina la 48 biti for(int i = 0; i < 48; i++){ RiExt[i] = Ri[Ext[i]-1]; } //Operatia XOR dintre partea dreapta extinsa si cheia corespunzatiare turului B = XOR(RiExt,Keyi); // construirea tabelului din 8 secvente a cite 6 biti for (int i = 0; i < 8; i++) { for (int j = 0; j < 6; j++) { bTable[i, j] = B[count]; count++; } } //Transformarea secventelor din 6 biti in 4 biti for(int i = 0; i< 8;i++){ for (int j = 0; j < 6; j++) { b6[j] = bTable[i, j]; } b4 += B6toB4(b6, i);//Functia de transformare } //Permutarea P cb4 = b4.ToCharArray(0,32); for(int i = 0; i < P.Length; i++) { Pb4[i] = cb4[P[i] - 1]; } return Pb4; //Intoarcerea secventei de 32 biti } //Functia de criptare a blocului de 64 biti string EncryptBloc(char[] Block, char[,] key) { string encodedText = string.Empty; char[] IPBlock = new char[64]; char[] Left = new char[32]; char[] Right = new char[32]; char[] keyI = new char[48]; char[] fResult = new char[56]; char [] Rinext = new char[32]; char[] L16R16 = new char[64]; char[] FPL16R16 = new char[64]; //Permutarea initiala for (int i = 0; i < Block.Length; i++) { IPBlock[i] = Block[IP[i]-1]; }

//Impartirea blocului de 64 biti in partea dreapta si stinga a cite 32 biti for(int i = 0; i < 32; i++) { Left[i] = IPBlock[i]; Right[i] = IPBlock[i+32]; } //Ciclul pentru 16 tururi de criptare a unui bloc for(int i = 0; i < 16; i++) { //extragerea cheii corespunzatoare iteratiei de criptare for( int j = 0; j < 48; j++ ) { keyI[j] = key[i,j]; } fResult = F(keyI, Right);// rezultatul functiei F //Sau exclusiv dintre rezultatul functiei F si partea stinga Rinext = XOR(Left, fResult); // schimbarea partii stingi cu partea dreapta for (int j = 0; j < 32; j++) { Left[j] = Right[j]; } for (int j = 0; j < 32; j++) { Right[j] = Rinext[j]; } } //Construirea din partea Stinga si Dreapta a unei secvente de 64 biti dupa a 16-lea tur for (int i = 0; i < 32; i++) { L16R16[i] = Left[i]; L16R16[i + 32] = Right[i]; } //Permutarea finala for (int i = 0; i < 64; i++) { FPL16R16[i] = L16R16[FP[i] - 1]; } //Conversia din secventa de biti in sir de caractere encodedText = convetFromCharArrayOfBitesToString(FPL16R16); return encodedText; } //Functia pentru cinversi din sirul de biti in sirul de carectere public string convetFromCharArrayOfBitesToString(char[] arr) { int start = 0; int stop = 8; int count = 0; int val = 0; string result = string.Empty; while(stop < 65){ // transformarea a 64biti in numar intreg for (int i = start; i < stop; i++) { switch (count) { case 0: if (arr[i] == '1') { val case 1: if (arr[i] == '1') { val case 2: if (arr[i] == '1') { val case 3: if (arr[i] == '1') { val case 4: if (arr[i] == '1') { val case 5: if (arr[i] == '1') { val case 6: if (arr[i] == '1') { val case 7: if (arr[i] == '1') { val } count++; } start +=8; stop +=8; count = 0; //Introducerea in sir de caractere a caracterul din tabelul ASCCII extins result += char.ConvertFromUtf32(val); val = 0; } return result; }

+= += += += += += += +=

128; } break; 64; } break; 32; } break; 16; } break; 8; } break; 4; } break; 2; } break; 1; } break;

echivalent cu numarul intreg

//Functia pentru rotatie circulara la stinga public char[] leftShift(char[] arr, int times) { char[] tmpShift = new char[times]; char[] tmpRemain = new char[arr.Length - times]; char[] resultArr = new char[arr.Length]; int j = 0; int r = 0; for (int i = 0; i < times; i++) { tmpShift[i] = arr[i]; } for (int i = times; i < arr.Length; i++) { tmpRemain[j] = arr[i]; j++; } j = 0; for (int i = r ; i < tmpRemain.Length; i++) { resultArr[i] = tmpRemain[i]; r++; } for (int i = 0; i < tmpShift.Length; i++) { resultArr[r] = tmpShift[i]; r++; } return resultArr; } // Functia pentru generarea a 16 chei public char[,] Generate16Keys(char[] key) { char[,] keys16 = new char[16,48]; char[] C0D0 = new char[56]; char[] C0 = new char[28]; char[] D0 = new char[28]; char[] Ci = new char[28]; char[] Di = new char[28]; char[] CiDi = new char[56]; char[] arrPC2 = new char[48]; //Eliminarea din cheia initiala a bitilor de paritare prin permutarea PC1 for (int i = 0; i < PC1.Length; i++) { C0D0[i] = key[PC1[i] - 1]; } int shiftTimes = 0; //Impartirea cheii de 56 biti in doua secvente a cite 28 biti for (int i = 0; i < 28; i++) { C0[i] = C0D0[i]; D0[i] = C0D0[i + 28]; } //Ciclul din pentru generarea a 16 chei for (int i = 0; i < 16; i++) { //Calcului mumarului de deplasari la stinga pentru cheia curenta for (int j = 0; j < i + 1; j++) { shiftTimes += Rot[j]; } Ci = leftShift(C0, shiftTimes);//Deplasarile la stinga Di = leftShift(D0, shiftTimes);//a fiecarei secvente de 28 biti shiftTimes = 0; //Construirea a unei secvente de 56 biti for (int q = 0; q < 28; q++) { CiDi[q] = Ci[q]; CiDi[q+28] = Di[q]; } //Permutarea PC2 for (int q = 0; q < 48; q++) { arrPC2[q] = CiDi[PC2[q] -1]; } //Introducerea cheii nou obtinute in tabel de chei for (int q = 0; q <48; q++) {

keys16[i,q] = arrPC2[q]; } } return keys16; //Intoarcerea a tabelului de 16 chei } //Functia pentru criptare sau decripatarea a siruli de caractere public string EncriptDecrypt(string Text, string Key, bool Encript) { char[] arr; char[] arrKey; char[,] keys16 = new char[16, 48]; int blocks = Text.Length / 8; int blockCount = 0; int len = 0; string result = string.Empty; string bintext = string.Empty; string binKey = string.Empty; string intermed = string.Empty; //transforamarea sirului de caractere in secventa de biti foreach (char ch in Text) { if (ch <= 128 && ch >= 64 ) { bintext += "0"; } else if (ch < 64 && ch >= 32) { bintext += "00"; } else if (ch < 32 && ch >= 16) { bintext += "000"; } else if (ch < 16 && ch >= 8) { bintext += "0000"; } else if (ch < 8 && ch >= 4) { bintext += "00000"; } else if (ch < 4 && ch >= 2) { bintext += "000000"; } else if (ch == 1 && ch == 0) { bintext += "0000000"; } intermed = Convert.ToString((int)ch, 2); bintext += intermed; len = bintext.Length; } // Transforamrea cheii in secventa de biti foreach (char ch in Key) { binKey += "00"; binKey += Convert.ToString((int)ch, 2); } arrKey = binKey.ToCharArray(0, 64); //Genereara a 16 chei keys16 = Generate16Keys(arrKey); // Ciclu de criptarea/decriptarea a fiecarui bloc a cite 64 biti while (blockCount < blocks) { arr = bintext.ToCharArray(0 + (64 * blockCount), 64); if (Encript) { result += EncryptBloc(arr, keys16); } else { result += DecryptBloc(arr, keys16); } int resLen = result.Length; blockCount++; } return result; } //functia pentru decriptarea blocului de 64 biti string DecryptBloc(char[] Block, char[,] key) { string encodedText = string.Empty; char[] IPBlock = new char[64]; char[] Left = new char[32]; char[] Right = new char[32]; char[] keyI = new char[48]; char[] fResult = new char[56]; char[] Linext = new char[32]; char[] L16R16 = new char[64]; char[] FPL16R16 = new char[64]; //Permutarea initiala for (int i = 0; i < Block.Length; i++) { IPBlock[i] = Block[IP[i] - 1]; } //impartirea a blocului de 64 biti in parte stinga si dreapta

for (int i = 0; i < 32; i++) { Left[i] = IPBlock[i]; Right[i] = IPBlock[i + 32]; } //16 iteratii de decriptare, incelem cu a 16 cheie for (int i = 15; i >= 0; i--) { for (int j = 0; j < 48; j++) { keyI[j] = key[i, j]; } //rezultatul functiei F fResult = F(keyI,Left); // Sau exclusiv dintre rezultatul functiei F si partea dreapta Linext = XOR(Right, fResult); //Atribuirea valorilar partilor drepte si stingi pentru iteratia urmatoare for (int j = 0; j < 32; j++) { Right[j] = Left[j]; } for (int j = 0; j < 32; j++) { Left[j] = Linext[j]; } } //Construirea din partea stinga si dreapta dupa a 16-a iteratie a sirului de 64 biti for (int i = 0; i < 32; i++) { L16R16[i] = Left[i]; L16R16[i + 32] = Right[i]; } //Permutarea finala for (int i = 0; i < 64; i++) { FPL16R16[i] = L16R16[FP[i] - 1]; } encodedText = convetFromCharArrayOfBitesToString(FPL16R16); return encodedText; } } }

Descrierea aplicatiei Interfaa grafic este format din o singur fereastr(Figura 3) cu campuri rezervate pentru mesajul ce urmeaz a fi criptat/decriptat, cheia de criptare/decriptare, 2 butoane pentru criptarea/decriptarea mesajului introdus, rezultatul rulrii algoritmului este prezentat in campul de mai jos de buton.

Figura 1. Fereastra principal a programului 9

Concluzie Realizarea acestei lucrri de laborator mi-a permis studierea unui algoritm de criptare din grupul celor cu cheie simetric, i anume algoritmul DES. n urma analizei acestui algoritm, am determinat paii care trebuie urmai pentru a efectua att criptarea ct i decriptarea determinnd pentru fiecare din operaii cteva calcule de transformare a mesajului iniial/criptat i a cheii comune n obinerea unui mesaj criptat/decriptat. n general consider c pentru aplicaii mici alroritmul DES este foarte comod de ntrebuinat deoarece este relativ sigur ns pentru sisteme mari acest algoritm va da locul altor algoritmi mai evoluai i siguri. Bibliografia: 1. .. 2. http://msdn.microsoft.com [Descrierea claselor, proprietilor i metodelor limbajului C#]

10