Vissza

4. labor: az RC4, az LFSR, az A51 titkosítók


1. Írjunk programot, mely RC4 módszerrel, egy 128 bites kulcsot használva, titkosít és visszafejt egy tetszőleges bináris állományt, ahol a kulcsot egy szövegállományból olvassuk ki, amelyben a kulcs hexadecimális alakját tároljuk. A rejtjelezés során az rc4_output első 1024 bájtját ne használjuk fel. Mérjük meg a rejtjelezés időigényét különböző méretű bináris állományok esetében.

2. A bináris docx állomány RC4-el volt titkosítva. Határozzuk meg a nyílt szöveget, azaz az eredeti állományt, ha meg van adva egy nyílt/titkosítottállománypár (known plaintext attack).

3. Írjuk ki az RC4 titkosító esetében az S tömb állapotát az inicializálási szakasz után, majd miután a kulcsfolyam első 100 bájtját kigenerálta az algoritmus, illetve 1000 bájt után. Az alkalmazott kulcs hexa értéke legyen a következő: 0x1A 0x2B 0x3C 0x4D 0x5E 0x6F 0x77.

4. Írjunk programot, mely A51 módszerrel titkosít és visszafejt egy tetszőleges bináris állományt, mérjük meg a rejtjelezés időigényét különböző méretű bináris állományok esetében.

5. A bináris jpg állomány 32 bites LFSR folyamtitkosítóval volt titkosítva. Határozzuk meg a nyílt szöveget, azaz az eredeti állományt, ha meg van adva egy hogy a 0xe0ffd8ff 464a1000 hexa érték titkosított értéke: 0x880006b0 de683e80.

6. Írjunk programot, amely LFSR-16 módszerrel egy kezdeti 16 bites kulcsot használva, titkosít és visszafejt egy tetszőleges bináris állományt, ahol a kulcsot egy szövegállományból olvassuk ki, amelyben a kulcs hexadecimális alakját tároljuk. Mérjük meg a rejtjelezés időigényét különböző méretű bináris állományok esetében.

Segédanyag

Az RC4 egy folyamtitkosító (stream cipher) algoritmus. Első lépésként egy kezdeti kulcs alapján egy tetszőleges hosszúságú kulcsfolyamot generál. Egy tetszőleges bináris állomány titkosítása egy időben történik a kulcsfolyam generálásával. A titkosítás bájtonként, a XOR művelet alkalmazásával történik, ahol a nyíltszöveg aktuális bájtját XOR-oljuk az éppen kigenerált kulcsfolyam megfelelő elemével

A kulcsfolyam wikipedián található implementációja C-ben a következő:

unsigned char S[256];
unsigned int i, j;

void swap(unsigned char *s, unsigned int i, unsigned int j) {
unsigned char temp = s[i];
s[i] = s[j];
s[j] = temp;
}

/* KSA: Key-scheduling algorithm */
/* As S tömb inicializálása: kezdetben megegyezik az identitás permutációval */
/* A 256-al történő maradékos osztás 255-tel való & (AND) muvelettel van megvalósítva*/
void rc4_init(unsigned char *key, unsigned int key_length) {
for (i = 0; i < 256; i++)
S[i] = i;

for (i = j = 0; i < 256; i++) {
j = (j + key[i % key_length] + S[i]) & 255;
swap(S, i, j);
}
i = j = 0;
}

/* PRGA: Pseudo-random genaration algorithm*/
/*Az álvéletlen értékeket meghatározó algoritmus*/

unsigned char rc4_output() {
i = (i + 1) & 255;
j = (j + S[i]) & 255;
swap(S, i, j);

return S[(S[i] + S[j]) & 255];
}

/*A foprogram, amely egy kezdeti kulcs alapján meghatározz a kulcsfolyamot*/
#include <stdio.h>
int main() {
int k, output_length;
//a kulcsfolyam létrehozása egy kezdeti kulcsérték, a key alapján történik
unsigned char key[] = "Cryptography";
rc4_init(key, 12); // a kulcs hossza 12

output_length = 40; //a kulcsfolyam hossza
k = 0;
while (k < output_length) {
printf("%c", rc4_output());
k++;
}
}

A kulcsfolyam Java implementációja a következő:

public class RC4_class {
public final int[] S;
public static int i, j;

public RC4_class (){
this.S = new int[256];
}

public static void swap(int []s, int i, int j) {
int temp = s[i];
s[i] = s[j];
s[j] = temp;
}

public void rc4_init(char[] key, int key_length) {
for (i = 0; i < 256; i++)
S[i] = i;

for (i = j = 0; i < 256; i++) {
j = (j + key[i % key_length] + S[i]) & 255;
swap(S, i, j);
}
i = j = 0;
}

public int rc4_output() {
i = (i + 1) & 255;
j = (j + S[i]) & 255;
swap(S, i, j);

return S[(S[i] + S[j]) & 255];
}
}

8 bites LFSR string-titkosítás:

typedef unsigned char uint8;
uint8 lfsr_output8(uint8 lfsr);
void crypt8(string& c, string m, uint8 lfsr);

int main() {
string m("This is a plaintext for 2017 crypt Lab! Try for longer text or file ");
uint8 lfsr = 0x87;
string c = "", m1 = "";
crypt8(c, m, lfsr);
cout << "crypted text: " << c << endl << endl << endl;

crypt8(m1, c, lfsr);
cout << "decrypted text: " << m1 << endl << endl << endl;
}

void crypt8(string& c, string m, uint8 lfsr){
for (int i = 0; i < m.length(); ++i) {
lfsr = lfsr_output8(lfsr);
c += m[i] ^ lfsr;
}
}

uint8 lfsr_output8(uint8 lfsr){
uint8 bit;
bit = ((lfsr >> 0) ^ (lfsr >> 3)) & 1;
lfsr = (lfsr >> 1) | (bit << 7);
return lfsr;
}

16 bites LFSR string-titkosítás:

typedef unsigned short uint16;
uint16 lfsr_output16(uint16 lfsr);
void crypt16(string &c, string m, uint16 lfsr);

void main() {
string m("This is a plaintext for 2017 crypt Lab!Try for longer text or file");
if (m.length() & 1) m += " ";
string m1 = "";
string c = "";
uint16 lfsr = 0x8735;

crypt16(c, m, lfsr);
cout << "crypted text: " << c << endl << endl << endl;
crypt16(m1, c, lfsr);
cout << "decrypted text: " << m1 << endl << endl << endl;
}

uint16 lfsr_output16(uint16 lfsr)<{
uint16 bit;
bit = ((lfsr >> 0) ^ (lfsr >> 2) ^ (lfsr >> 3) ^ (lfsr >> 5)) & 1;
lfsr = (lfsr >> 1) | (bit << 15);
return lfsr;
}

void crypt16(string &c, string m, uint16 lfsr) {
uint16 temp;
for (int i = 0; i < m.length(); i += 2) {
lfsr = lfsr_output16(lfsr);
temp = ((uint8)m[i] << 8) | (uint8)m[i + 1];
temp = temp ^ lfsr;

uint8 st1 = temp >> 8;
c += st1;
uint8 st2 = 0xff;
temp = temp & st2;
c += temp;
}
}