Список используемых источников

1. С.Г. Баричев, В.В. Гончаров, Р.Е. Серов, Основы современной криптографии, 2-е издание, Москва, "Горячая линия - Телеком", 2002.

2. Осипенко Л. П., Васильченко А. А. Математические основы криптологии. Методические указания для выполнения курсовой работы. – Краснодар: Изд-во КубГТУ, 2009.

3. Кнут Д. Искусство программирования. Т. 2. По­лучисленные алгоритмы. третье издание. М.: МЦНМО, 1999.

4. http://ru.wikipedia.org/wiki/Rijndael

5. http://kavayii.blogspot.com/2010/02/advanced-encryption-standard-aes-2-aes.html

6. http://book.itep.ru/6/aes.htm

7. http://ru.wikipedia.org/wiki/Конечное_поле

8. http://www.pm298.ru/mgroup.php

9. http://ru.wikipedia.org/wiki/Поле_(алгебра)

Приложение А

Список используемых источников - student2.ru

Рисунок 5 – Скриншот программы

Приложение Б

Листинг программы

using System;

using System.Collections.Generic;

using System.ComponentModel;

using System.Data;

using System.Drawing;

using System.Linq;

using System.Text;

using System.Windows.Forms;

namespace CryptoAES

{

public partial class Form1 : Form

{

public Form1()

{

InitializeComponent();

}

//public static string[,] Tabl;

public static string ByteToHex(byte a)

{

string hex="";

int b = a / 16;

int c = a % 16;

switch (b)

{

case 0:

hex += '0';

break;

case 1:

hex += '1';

break;

case 2:

hex += '2';

break;

case 3:

hex += '3';

break;

case 4:

hex += '4';

break;

case 5:

hex += '5';

break;

case 6:

hex += '6';

break;

case 7:

hex += '7';

break;

case 8:

hex += '8';

break;

case 9:

hex += '9';

break;

case 10:

hex += 'A';

break;

case 11:

hex += 'B';

break;

case 12:

hex += 'C';

break;

case 13:

hex += 'D';

break;

case 14:

hex += 'E';

break;

case 15:

hex += 'F';

break;

}

switch (c)

{

case 0:

hex += '0';

break;

case 1:

hex += '1';

break;

case 2:

hex += '2';

break;

case 3:

hex += '3';

break;

case 4:

hex += '4';

break;

case 5:

hex += '5';

break;

case 6:

hex += '6';

break;

case 7:

hex += '7';

break;

case 8:

hex += '8';

break;

case 9:

hex += '9';

break;

case 10:

hex += 'A';

break;

case 11:

hex += 'B';

break;

case 12:

hex += 'C';

break;

case 13:

hex += 'D';

break;

case 14:

hex += 'E';

break;

case 15:

hex += 'F';

break;

}

return hex;

}

public static byte HexToByte(string hex)

{

byte a=0;

switch (hex[1])

{

case '0':

a = 0;

break;

case '1':

a = 1;

break;

case '2':

a = 2;

break;

case '3':

a = 3;

break;

case '4':

a = 4;

break;

case '5':

a = 5;

break;

case '6':

a = 6;

break;

case '7':

a = 7;

break;

case '8':

a = 8;

break;

case '9':

a = 9;

break;

case 'A':

a = 10;

break;

case 'B':

a = 11;

break;

case 'C':

a = 12;

break;

case 'D':

a = 13;

break;

case 'E':

a = 14;

break;

case 'F':

a = 15;

break;

}

switch (hex[0])

{

case '0':

a += 0;

break;

case '1':

a += 16;

break;

case '2':

a += 32;

break;

case '3':

a += 48;

break;

case '4':

a += 64;

break;

case '5':

a += 80;

break;

case '6':

a += 96;

break;

case '7':

a += 112;

break;

case '8':

a += 128;

break;

case '9':

a += 144;

break;

case 'A':

a += 160;

break;

case 'B':

a += 176;

break;

case 'C':

a += 192;

break;

case 'D':

a += 208;

break;

case 'E':

a += 224;

break;

case 'F':

a += 240;

break;

}

return a;

}

private void button1_Click(object sender, EventArgs e)

{

byte[] input;

if (richTextBox1.Text.Length%16==0)

input = new byte[richTextBox1.Text.Length];

else

input = new byte[((richTextBox1.Text.Length/16)+1)*16];

for (int i = 0; i < richTextBox1.Text.Length; i++)

input[i] = Convert.ToByte(richTextBox1.Text[i]);

for (int i = richTextBox1.Text.Length; i < input.Length; i++)

input[i] = 0;

//------------------------------------

byte[] key = new byte[1];

if (textBox1.Text.Length <= 16)

key = new byte[16];

if (textBox1.Text.Length > 16 && textBox1.Text.Length <=24)

key = new byte[24];

if (textBox1.Text.Length > 24)

key = new byte[32];

for (int i = 0; i < textBox1.Text.Length; i++)

key[i] = Convert.ToByte(textBox1.Text[i]);

for (int i = textBox1.Text.Length; i < key.Length; i++)

key[i] = 0;

//------------------------------------

AES.Encrypt(ref input, key);

/*TablLeng.ColumnCount = 16;

TablLeng.RowCount = 16;

for (int q = 0; q <= 15; q++)

{

TablLeng.Columns[q].Width = 40;

TablLeng.Columns[q].Name = Convert.ToString(q);

}

int oi = 0;

for (int l = 0; l < 16; l++)

{

for (int q = 0; q < 16; q++)

{

TablLeng[q, l].Value = Tabl[q, l];

oi++;

}

}*/

string txt="";

string[] HexTable = new string[256];

for (int i = 0; i < 256; i++)

{

HexTable[i] = ByteToHex(Convert.ToByte(i));

}

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

{

txt += HexTable[input[i]];

}

richTextBox2.Text = txt;

}

private void button2_Click(object sender, EventArgs e)

{

byte[] input = new byte[richTextBox2.Text.Length/2];

string txt="";

for (int i = 0; i < richTextBox2.Text.Length; i+=2)

{

txt=Convert.ToString(richTextBox2.Text[i])+Convert.ToString(richTextBox2.Text[i+1]);

input[i/2] = HexToByte(txt);

}

//------------------------------------

byte[] key = new byte[1];

if (textBox1.Text.Length <= 16)

key = new byte[16];

if (textBox1.Text.Length > 16 && textBox1.Text.Length <= 24)

key = new byte[24];

if (textBox1.Text.Length > 24)

key = new byte[32];

for (int i = 0; i < textBox1.Text.Length; i++)

key[i] = Convert.ToByte(textBox1.Text[i]);

for (int i = textBox1.Text.Length; i < key.Length; i++)

key[i] = 0;

//------------------------------------

AES.Decrypt(ref input, key);

/*TablLeng.ColumnCount = 16;

TablLeng.RowCount = 16;

for (int q = 0; q <= 15; q++)

{

TablLeng.Columns[q].Width = 40;

TablLeng.Columns[q].Name = Convert.ToString(q);

}

int oi = 0;

for (int l = 0; l < 16; l++)

{

for (int q = 0; q < 16; q++)

{

TablLeng[q, l].Value = Tabl[q, l];

oi++;

}

}*/

txt = "";

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

txt += Convert.ToChar(input[i]);

richTextBox1.Text = txt;

}

private void textBox1_TextChanged(object sender, EventArgs e)

{

if (textBox1.Text.Length <= 16)

label4.Text = "- 128 бит";

if (textBox1.Text.Length > 16 && textBox1.Text.Length <= 24)

label4.Text = "- 192 бит";

if (textBox1.Text.Length > 24)

label4.Text = "- 256 бит";

}

}

class AES

{

#region Create S-Box or InvS-Box

private static void Create_InvSBox(ref byte[] InvSBox)

{

byte[] SBox = new byte[256];

for (int i = 0; i <= 255; i++)

{

byte result = Convert.ToByte(i);

for (int q = 1; q < 7; q++)

result = AES.PolynomsMult(AES.PolynomsMult(result, result, 0x11b), Convert.ToByte(i), 0x11b);

result = AES.PolynomsMult(result, result, 0x11b);

result = AES.PolynomsMult(0x1f, result, 0x101);

SBox[i] = Convert.ToByte(result ^ 0x63);

}

for (int i = 0; i <= 255; i++)

{

InvSBox[SBox[i]] = Convert.ToByte(i);

}

}

private static void Create_SBox(ref byte[] SBox)

{

for (int i = 0; i <= 255; i++)

{

byte result = Convert.ToByte(i);

for (int q = 1; q < 7; q++)

result = AES.PolynomsMult(AES.PolynomsMult(result, result, 0x11b), Convert.ToByte(i), 0x11b);

result = AES.PolynomsMult(result, result, 0x11b);

result = AES.PolynomsMult(0x1f, result, 0x101);

SBox[i] = Convert.ToByte(result ^ 0x63);

}

}

#endregion

#region Multiply Polynoms

private static byte PolynomsMult(byte a, byte b, ushort mod)

{

ushort mult = 0;

ushort temp = b;

while (a > 0)

{

if ((a & 0x01) == 1) mult ^= temp;

a >>= 1;

temp <<= 1;

}

for (byte i = 14; i >= 8; i--)

if ((mult >> i) == 1) mult = Convert.ToUInt16(mult ^ (mod << (i - 8)));

return Convert.ToByte(mult);

}

#endregion

#region Key schedule

private static byte[,] KeyExpansion(byte[] key, byte[] SBox)

{

byte[] RCon= new byte[] { 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36 };

byte[,] AKey = new byte[4,60];

for (int i = 0; i < 60; i++ )

{

for (int q = 0; q < 4; q++)

AKey[q, i] = 0;

}

if (key.Length == 16)

{

AKey = new byte[4, 44];

byte ch = 0;

for (int i = 0; i < 4; i++)

{

for (int q = 0; q < 4; q++)

{

AKey[i, q] = key[ch];

ch++;

}

}

for (int i = 4; i < 44; i++)

{

byte[] temp = new byte[4];

for (int q = 0; q < 4; q++)

{

temp[q] = AKey[q, i - 1];

}

if ((i % 4) == 0)

{

temp = SubWord(RotWord(temp), SBox);

temp[0] ^= RCon[(i / 4) - 1];

}

for (int q = 0; q < 4; q++)

AKey[q, i] = Convert.ToByte(AKey[q, i - 4] ^ temp[q]);

}

}

if (key.Length == 24)

{

AKey = new byte[4, 52];

byte ch = 0;

for (int i = 0; i < 4; i++)

{

for (int q = 0; q < 6; q++)

{

AKey[i, q] = key[ch];

ch++;

}

}

for (int i = 6; i < 52; i++)

{

byte[] temp = new byte[4];

for (int q = 0; q < 4; q++)

{

temp[q] = AKey[q, i - 1];

}

if ((i % 6) == 0)

{

temp = SubWord(RotWord(temp), SBox);

for (int q = 0; q < 4; q++)

{

temp[q] ^= RCon[q];

}

}

else if (i % 6 == 3)

{

temp = SubWord(temp, SBox);

}

for (int q = 0; q < 4; q++)

AKey[q, i] = Convert.ToByte(AKey[q, i - 6] ^ temp[q]);

}

}

if (key.Length == 32)

{

AKey = new byte[4, 60];

byte ch = 0;

for (int i = 0; i < 4; i++)

{

for (int q = 0; q < 8; q++)

{

AKey[i, q] = key[ch];

ch++;

}

}

for (int i = 8; i < 60; i++)

{

byte[] temp = new byte[4];

for (int q = 0; q < 4; q++)

{

temp[q] = AKey[q, i - 1];

}

if ((i % 8) == 0)

{

temp = SubWord(RotWord(temp), SBox);

for (int q = 0; q < 4; q++)

{

temp[q] ^= RCon[q];

}

}

else if (i % 8 == 4)

{

temp = SubWord(temp,SBox);

}

for (int q=0; q<4; q++)

AKey[q,i] = Convert.ToByte(AKey[q,i - 8] ^ temp[q]);

}

}

return AKey;

}

private static byte[] SubWord(byte[] W, byte[] SBox)

{

byte[] temp = new byte[4];

for (int i = 0; i < 4; i++)

temp[i] = SBox[W[i]];

return temp;

}

private static byte[] RotWord(byte[] W)

{

byte[] temp = new byte[4];

for (int i = 0; i < 4; i++)

temp[i] = W[(i + 1)%4];

return temp;

}

#endregion

#region Block_Encrypt or Block_Decrypt

private static void Cipher(ref byte[,] state, byte[,] AKey, byte[] SBox, byte length)

{

AddRoundKey(ref state, AKey, 0);

for (int round = 1; round <= 9+length*2; round++)

{

SubBytes(ref state, SBox);

ShiftRows(ref state);

MixColumns(ref state);

AddRoundKey(ref state, AKey, round*4);

}

SubBytes(ref state,SBox);

ShiftRows(ref state);

AddRoundKey(ref state, AKey, 40+length*8);

}

private static void InvCipher(ref byte[,] state, byte[,] AKey, byte[] InvSBox, byte length)

{

AddRoundKey(ref state, AKey, 40 + length * 8);

InvShiftRows(ref state);

SubBytes(ref state, InvSBox);

for (int round = 9 + length * 2; round >= 1; round--)

{

AddRoundKey(ref state, AKey, round * 4);

InvMixColumns(ref state);

InvShiftRows(ref state);

SubBytes(ref state, InvSBox);

}

AddRoundKey(ref state, AKey, 0);

}

private static void MixColumns(ref byte[,] state)

{

byte[,] new_state = new byte[4, 4];

for (int c = 0; c < 4; c++)

{

new_state[0, c] = (byte)(PolynomsMult(2, state[0, c], 283) ^ PolynomsMult(3, state[1, c], 283) ^ state[2, c] ^ state[3, c]);

new_state[1, c] = (byte)(state[0, c] ^ PolynomsMult(2, state[1, c],283) ^ PolynomsMult(3, state[2, c], 283) ^ state[3, c]);

new_state[2, c] = (byte)(state[0, c] ^ state[1, c] ^ PolynomsMult(2, state[2, c],283) ^ PolynomsMult(3, state[3, c],283));

new_state[3, c] = (byte)(PolynomsMult(3, state[0, c],283) ^ state[1, c] ^ state[2, c] ^ PolynomsMult(2, state[3, c],283));

}

state = new_state;

return;

}

private static void InvMixColumns(ref byte[,] state)

{

byte[,] new_state = new byte[4, 4];

for (int c = 0; c < 4; c++)

{

new_state[0, c] = (byte)(AES.PolynomsMult(14, state[0, c], 283) ^ AES.PolynomsMult(11, state[1, c], 283) ^ AES.PolynomsMult(13, state[2, c], 283) ^ AES.PolynomsMult(9, state[3, c], 283));

new_state[1, c] = (byte)(AES.PolynomsMult(9, state[0, c], 283) ^ AES.PolynomsMult(14, state[1, c], 283) ^ AES.PolynomsMult(11, state[2, c], 283) ^ AES.PolynomsMult(13, state[3, c], 283));

new_state[2, c] = (byte)(AES.PolynomsMult(13, state[0, c], 283) ^ AES.PolynomsMult(9, state[1, c], 283) ^ AES.PolynomsMult(14, state[2, c], 283) ^ AES.PolynomsMult(11, state[3, c], 283));

new_state[3, c] = (byte)(AES.PolynomsMult(11, state[0, c], 283) ^ AES.PolynomsMult(13, state[1, c], 283) ^ AES.PolynomsMult(9, state[2, c], 283) ^ AES.PolynomsMult(14, state[3, c], 283));

}

state = new_state;

}

private static void ShiftRows(ref byte[,] state)

{

byte[,] temp = new byte[4,4];

for (int i = 0; i < 4; i++)

{

for (int q = 0; q < 4; q++)

temp[i, q] = state[i, (q + i) % 4];

}

state = temp;

}

private static void InvShiftRows(ref byte[,] state)

{

byte[,] temp = new byte[4, 4];

for (int i = 0; i < 4; i++)

{

for (int q = 0; q < 4; q++)

temp[i, q] = state[i, (q + 4 - i) % 4];

}

state = temp;

}

private static void SubBytes(ref byte[,] state, byte[] SBox)

{

for (int i = 0; i < 4; i++)

{

for (int q = 0; q < 4; q++)

{

state[i, q] = SBox[state[i,q]];

}

}

}

private static void AddRoundKey(ref byte[,] state, byte[,] AKey, int round)

{

for (int i = 0; i < 4; i++)

{

for (int q = 0; q < 4; q++)

{

state[i, q] ^= AKey[i,q+round];

}

}

}

#endregion

#region Encrypt or Decrypt text

public static void Encrypt(ref byte[] array, byte[] key)

{

byte[,] temp = new byte[4,4];

byte[] SBox = new byte[256];

Create_SBox(ref SBox);

/*Form1.Tabl = new string[16, 16];

int oi = 0;

for (int l = 0; l < 16; l++)

{

for (int q = 0; q < 16; q++)

{

Form1.Tabl[q, l] = Form1.ByteToHex(SBox[oi]);

oi++;

}

}*/

byte[,] AKey = KeyExpansion(key,SBox);

uint len = (uint)(array.Length / 16);

byte[] output = new byte[len*16];

byte j = 0;

for (int i = 0; i < len; i++)

{

for (int k = 0; k < 4; k++)

{

for (int q = 0; q < 4; q++)

{

temp[k, q] = array[16 * i + j];

j++;

}

}

j = 0;

Cipher(ref temp, AKey, SBox, Convert.ToByte((key.Length - 16) / 8));

for (int k = 0; k < 4; k++)

{

for (int q = 0; q < 4; q++)

{

output[16 * i + j] = temp[k,q];

j++;

}

}

j = 0;

}

array = output;

Array.Clear(AKey, 0, AKey.Length);

}

public static void Decrypt(ref byte[] array, byte[] key)

{

byte[,] temp = new byte[4,4];

byte[] InvSBox = new byte[256];

byte[] SBox = new byte[256];

Create_SBox(ref SBox);

Create_InvSBox(ref InvSBox);

/*Form1.Tabl = new string[16, 16];

int oi = 0;

for (int l = 0; l < 16; l++)

{

for (int q = 0; q < 16; q++)

{

Form1.Tabl[q, l] = Form1.ByteToHex(InvSBox[oi]);

oi++;

}

}*/

byte[,] AKey = KeyExpansion(key, SBox);

uint len = (uint)(array.Length / 16);

byte[] output = new byte[len * 16];

byte j = 0;

for (int i = 0; i < len; i++)

{

for (int k = 0; k < 4; k++)

{

for (int q = 0; q < 4; q++)

{

temp[k, q] = array[16 * i + j];

j++;

}

}

j = 0;

InvCipher(ref temp, AKey, InvSBox, Convert.ToByte((key.Length - 16) / 8));

for (int k = 0; k < 4; k++)

{

for (int q = 0; q < 4; q++)

{

output[16 * i + j] = temp[k, q];

j++;

}

}

j = 0;

}

array = output;

Array.Clear(AKey, 0, AKey.Length);

}

#endregion

#region Test

private static void test()

{

byte[,] state = new byte[4, 4];

state[0, 0] = 0x32;

state[0, 1] = 0x88;

state[0, 2] = 0x31;

state[0, 3] = 0xe0;

state[1, 0] = 0x43;

state[1, 1] = 0x5a;

state[1, 2] = 0x31;

state[1, 3] = 0x37;

state[2, 0] = 0xf6;

state[2, 1] = 0x30;

state[2, 2] = 0x98;

state[2, 3] = 0x07;

state[3, 0] = 0xa8;

state[3, 1] = 0x8d;

state[3, 2] = 0xa2;

state[3, 3] = 0x34;

byte[] key = new byte[16];

key[0] = 0x2b;

key[1] = 0x28;

key[2] = 0xab;

key[3] = 0x09;

key[4] = 0x7e;

key[5] = 0xae;

key[6] = 0xf7;

key[7] = 0xcf;

key[8] = 0x15;

key[9] = 0xd2;

key[10] = 0x15;

key[11] = 0x4f;

key[12] = 0x16;

key[13] = 0xa6;

key[14] = 0x88;

key[15] = 0x3c;

byte[] SBox = new byte[256];

byte[] InvSBox = new byte[256];

AES.Create_SBox(ref SBox);

AES.Create_InvSBox(ref InvSBox);

byte[,] AKey = AES.KeyExpansion(key, SBox);

AES.Cipher(ref state, AKey, SBox, 0);

AES.InvCipher(ref state, AKey, InvSBox, 0);

}

#endregion

}

}

Наши рекомендации