Sunteți pe pagina 1din 8

Ministerul Educației al Republicii Moldova

Universitatea Tehnică a Moldovei


Facultatea Calculatoare, Informatică și Microelectronică
Catedra Automatica și Tehnologii Informaționale

RAPORT
Disciplina: Securitatea Informațională

Laboratorul nr. 1

Tema: Algoritmi de criptare clasici. Algoritmul DES

A efectuat studentul grupei TI-111, Voloceai Petru

A verificat: Lector Superior, V. Olaru

Chişinǎu 2014

Scopul lucrării
Studierea algoritmilor de criptare al datelor folosind metode de substituție. Studierea algori
simetric DES.
Obiectivele lucrării
Crearea aplicațiilor care implementează următoarele metode de criptare și de decriptare al datelor:
a) Cifrul lui Caesar
b) Cifrul lui Polybius
c) Cifrul lui Trithemius
Implementarea unei aplicații în care este utilizat algoritmul DES.

Realizarea lucrării
Lucrarea de laborator a fost realizată în mediul Intellij IDEA utilizînd tehnologiile java.
Mesajul care va fi criptat va fi: The secret message.

Cifrul lui Cezar

Fig. 1 – Procesul de lucru al algoritmului Cezar.


Aplicarea cifrului lui Cezar asupra unui text oarecare constă în înlocuirea fiecărei litere din textul
iniţial cu una care se află la o distanţă fixă în alfabet. Acest exemplu este cu o deplasare de trei poziţii,
astfel încât B din textul iniţial devine E în textul criptat.
Transformarea poate fi reprezentată printr-o aliniere a două alfabete; alfabetul cifrului este
alfabetului normal rotat la stânga sau la dreapta cu un număr de poziții. În exemplul de mai jos cifrul
folosește o rotație la stânga cu cinci poziții (parametrul de deplasare, aici 12, este folosit drept cheia
cifrării).

Fig. 2 – Rezultatele algoritmului Cezar.


Codul îl puteți găsi în ANEXĂ.

Cifrul lui Polybius

2
Necătînd la faptul ca cifrul a fost creat pentru codare, cu ajutorul lui la fel se poate și codifica
mesaje. Pentru a codifica mesajul este necesar de a îndeplini următorii pași:
1. Formarea tabelului de criptare. Pentru fiecare limbă în parte, un tabel cu aceeași criptare
(opțional) Numărul de rânduri și coloane numerotate, parametrii de care depinde capacitatea sa
(numărul de litere din alfabet). Luate două numere întregi a căror produs este cel mai aproape de
numărul de scrisori în limba - obține numărul dorit de rânduri și coloane. Apoi am intra în tabel
toate literele alfabetului într-un rând - unul pentru fiecare celulă. Cu un deficit de celule pot fi
introduse într-una sau două litere (rar utilizate sau similare în uz).
2. Principiul codificării. Criptarea pe piața găsit scrisoarea textului și introdus în partea de jos a
acestuia codificate în aceeași coloană. În cazul în care scrisoarea a fost linia de jos, apoi a luat
partea de sus a aceeași coloană.

Fig. 3 – Rezultatele algoritmului Polybius.


Codul îl puteți găsi în ANEXĂ.

Cifrul lui Trithemius


Trithemius folosit tabula recta pentru a defini un cifru polyalphabetic. Tabula recta se face adesea
referire la discutarea cifrurile pre-calculator, inclusiv cifrul Vigenere și mai puțin bine-cunoscut cifrul
autokey Blaise de Vigenere lui. Toate cifruri polyalphabetic bazate pe cifruri Cezar poate fi descrisă în
termeni de tabula recta.

3
Fig. 4 – Tabula recta.

Acesta folosește un pătrat cu 26 de litere ale alfabetului următorul 26 de rânduri de litere


suplimentare, fiecare mutat odată la stânga. Acest lucru creează 26 de cifruri Cezar diferite.

Această metodă elimină frecvențele scrisoare din textul cifrat, ceea ce face să apară ca un șir
aleator sau bloc de date. Cu toate acestea, în cazul în care o persoană este conștient de faptul că această
metodă este folosit, devine usor de spart. Cifrul este vulnerabil la atac, deoarece nu are o cheie, care se
spune că pentru a rupe principiu Kerckhoffs, o regulă de criptologie.

Fig. 5 – Rezultatele algoritmului Trithemius.


Codul îl puteți găsi în ANEXĂ.

DES
Standardul de Criptare a Datelor (în engleză Data Encryption Standard, DES) este un cifru (o
metodă de criptare a informației), selectat ca standard federal de procesare a informațiilor în Statele Unite
în 1976, și care s-a bucurat ulterior de o largă utilizare pe plan internațional. Algoritmul a fost
controversat inițial, având elemente secrete, lungimea cheii scurtă și fiind bănuit că ascunde de fapt o
portiță pentru NSA. DES a fost analizat intens de către profesionaliști în domeniu și a motivat înțelegerea
cifrurilor bloc și criptanaliza lor.

DES este astăzi considerat nesigur pentru multe aplicații. Acest lucru se datorează în principiu
cheii de 56 de biți, considerată prea scurtă; cheile DES au fost sparte în mai puțin de 24 de ore. De
asemenea, există unele rezultate analitice care demonstrează slăbiciunile teoretice ale cifrului, deși nu este
fezabilă aplicarea lor. Se crede că algoritmul este practic sigur în forma Triplu DES, deși există atacuri
teoretice și asupra acestuia. În ultimii ani, cifrul a fost înlocuit de Advanced Encryption Standard (AES).

Fig. 6 – Rezultatele algoritmului DES.


Codul îl puteți găsi în ANEXĂ.

4
Concluzie
În urma efectuării lucrării de laborator am făcut cunoștință cu algoritmii clasici de criptare care stau
la baza algoritmilor de cifrare moderni. Cifruri simetrice au fost istoric sensibile la atacuri cunoscute
plaintext, atacuri plaintext alese, criptanaliza diferențială și criptanaliza liniară. Construcție atentă a
funcțiilor pentru fiecare rundă poate reduce foarte mult șansele de un atac de succes.

ANEXĂ
/** Caesar.java **/
package Ciphers.classic;

/**
* Created by vlc on 12/12/14.
*/
public class Caesar {

public static String decode(String enc, int offset) {


return encode(enc, 26 - offset);
}

public static String encode(String enc, int offset) {

offset = offset % 26 + 26;


StringBuilder encoded = new StringBuilder();
for (char i : enc.toCharArray()) {
if (Character.isLetter(i)) {
if (Character.isUpperCase(i))
encoded.append((char) ('A' + (i - 'A' + offset) % 26 ));
else
encoded.append((char) ('a' + (i - 'a' + offset) % 26 ));
} else
encoded.append(i);
}

return encoded.toString();
}
}

/** Polybius.java **/


package Ciphers.classic;

import java.awt.*;

/**
* Created by maxim on 11/30/14.
*/
public class Polybius {

public static char[][] charTable;


public static Point[] positions;

public static String prepareText(String s, boolean JtoI) {


s = s.toUpperCase().replaceAll("[^A-Z]", "");
return JtoI ? s.replace("J", "I") : s.replace("Q", "");
}

public static void createTable(String key, boolean JtoI) {

5
charTable = new char[5][5];
positions = new Point[26];

String s = prepareText(key + "ABCDEFGHIJKLMNOPQRSTUVWXYZ", JtoI);

int len = s.length();


for (int i = 0, k = 0; i < len; i++) {
char c = s.charAt(i);
if (positions[c - 'A'] == null) {
charTable[k / 5][k % 5] = c;
positions[c - 'A'] = new Point(k % 5, k / 5);
k++;
}
}
}

public static String encode(String in) {


StringBuilder sb = new StringBuilder(in);

for (int i = 0; i < sb.length(); i += 2) {

if (i == sb.length() - 1)
sb.append(sb.length() % 2 == 1 ? 'X' : "");

else if (sb.charAt(i) == sb.charAt(i + 1))


sb.insert(i + 1, 'X');
}
return codec(sb, 1);
}

public static String decode(String out) {


return codec(new StringBuilder(out), 4);
}

public static String codec(StringBuilder txt, int dir) {


int len = txt.length();
for (int i = 0; i < len; i += 2) {
char a = txt.charAt(i);
char b = txt.charAt(i + 1);

int r1 = positions[a - 'A'].y;


int r2 = positions[b - 'A'].y;
int c1 = positions[a - 'A'].x;
int c2 = positions[b - 'A'].x;

if (r1 == r2) {
c1 = (c1 + dir) % 5;
c2 = (c2 + dir) % 5;

} else if (c1 == c2) {


r1 = (r1 + dir) % 5;
r2 = (r2 + dir) % 5;

} else {
int tmp = c1;
c1 = c2;
c2 = tmp;
}

txt.setCharAt(i, charTable[r1][c1]);
txt.setCharAt(i + 1, charTable[r2][c2]);
}
return txt.toString();

6
}
}

/** Trithemius.java **/


package Ciphers.classic;

/**
* Created by vlc on 12/18/14.
*/
public class Trithemius {

static char[] lAlphabet = {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k',
'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'};
static char[] uAlphabet = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K',
'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'};

public static String decipher(String input, Integer initialOffset) {


Integer currentOffset = (((-1*initialOffset)+26)%26);
StringBuilder output = new StringBuilder();

// Loop through each character


for (int i = 0; i < input.length(); i++) {

if (Character.isLetter(input.charAt(i))) {

output.append(shiftLetter(currentOffset, input.charAt(i)));
currentOffset = (currentOffset+1)%26;

} else
output.append(input.charAt(i));
}

return output.toString();
}

public static String encipher(String input, Integer initialOffset) {


Integer currentOffset = initialOffset;

StringBuilder output = new StringBuilder();

// Loop through each character


for (int i = 0; i < input.length(); i++) {

if (Character.isLetter(input.charAt(i))) {

output.append(shiftLetter(currentOffset, input.charAt(i)));
currentOffset = ((currentOffset-1)+26)%26;

} else
output.append(input.charAt(i));
}

return output.toString();
}

public static char shiftLetter(int byOffset, char c) {


byOffset = byOffset % 26;
int[] thisPosition = findIndex(c);
if (thisPosition[1] == 0) { // Lowercase
return lAlphabet[((thisPosition[0]+byOffset)%26)];
} else { // Uppercase
return uAlphabet[((thisPosition[0]+byOffset)%26)];

7
}
}

public static int[] findIndex(char c) {


// Loop through the lowercase array
for (int i = 0; i < lAlphabet.length; i++) {
if (lAlphabet[i] == c) {
int[] result = {i, 0};
return result;
}
}
// Must be uppercase
for (int i = 0; i < uAlphabet.length; i++) {
if (uAlphabet[i] == c) {
int[] result = {i, 1};
return result;
}
}
int[] result = {-1, -1};
return result;
}
}

/** DES **/


package Ciphers;

import javax.crypto.*;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;

/**
* Created by vlc on 12/23/14.
*/
public class DES {

Cipher ecipher;
Cipher dcipher;

public DES(SecretKey key) throws NoSuchAlgorithmException,


NoSuchPaddingException, InvalidKeyException {
ecipher = Cipher.getInstance("DES");
dcipher = Cipher.getInstance("DES");
ecipher.init(Cipher.ENCRYPT_MODE, key);
dcipher.init(Cipher.DECRYPT_MODE, key);
}

public String encrypt(String str) throws UnsupportedEncodingException,


IllegalBlockSizeException, BadPaddingException {
byte[] utf8 = str.getBytes("UTF8");
byte[] enc = ecipher.doFinal(utf8);
return new sun.misc.BASE64Encoder().encode(enc);
}

public String decrypt(String str) throws IOException, IllegalBlockSizeException,


BadPaddingException {
byte[] dec = new sun.misc.BASE64Decoder().decodeBuffer(str);
byte[] utf8 = dcipher.doFinal(dec);
return new String(utf8, "UTF8");
}
}