Professional Documents
Culture Documents
RAPORT
A efectuat : A verificat:
Chiinu 2013
Sistemele criptografice simetrice Sistemele criptografice simetrice folosesc aceeai cheie K, att la cifrarea (criptarea) ct i la descifrarea (decriptarea) mesajelor. Cheia este secret i este folosit n comun de ctre emitor, cel care cifreaz mesajul M i de ctre receptor, cel care descifreaz criptograma C. 1. Algoritmul AES Matricea de stare Operaiile interne ale algoritmului AES se realizeaz pe o matrice bidimensional de octei numit matrice de stare. Matricea de stare este format din 4 rnduri de , fiecare coninnd Nb octei, unde Nb este egal cu lungimea blocului mprit la 32. Un element din matricea de stare se noteaz cu s r,c sau s[r,c] (rndul r i coloana c). Elementele sunt repretate n baza 16 (hexazecimal). n cadrul criptrii respectiv decriptrii, vectorii de intrare (in 1..15) sunt copiai n matricea de stare dup regula: s[r,c] = in[r + 4c] dup care toate prelucrrile necesare obinerii vectorilor de ieire (out 1..15 se vor efectua pe matricea de stare (Fig. 1).
Elementele vectorilor de ieire sunt copiai din matricea de stare la finalul criptrii dup regula: out[s+4c] = s[r,c] Elementele matricii de stare, care sunt constituite din 4 octei, se pot rescrie sub forma unor cuvinte de 32 de biti sub forma: wi = s 0,i s 1,i s 2,i s 3,i 2. Descrierea mecanismului de criptare La nceputul criptrii, secvena de la intrare este copiat n matricea de stare folosindu-se conveniile de construcie a matricii de control. Dup ce iniial a fost adugt cheia, matricea de stare este transformat prin implementarea funciei ciclice de 10, 12 sau 14 ori ( n funcie de lungimea cheii de criptare ) cu ultimul ciclu diferind puin de celelalte precedente. Matricea final de stare este apoi copiat la ieire. Funcia ciclic este parametrizat folosindu-se un program al cheii care ntr-un ir de cuvinte pe patru octei derivat, folosindu-se rutina de extindere a cheii descris n urmatoarea seciune. n Fig.2 este descris pseudo-codul cifrrii, n care transformrile individuale SubBytes(), ShiftRows(), MixColumns() i AddRoundKey() proceseaz matricea de stare i vor fi descrise n urmtoarele seciuni.
n aceast figur irul w[] reprezint programarea cheii, iar toate ciclurile de criptare sunt identice, excepie fcnd ciclul final care nu include funcia MixColumns(). Descrierea funciilor utilizate pentru criptare 2.1 Funcia SubBytes() Aceast funcie execut o transformare neliniar prin care sunt substituii octeii din matricea de stare prin utilizarea tabelului de substituie S-box. Acest tabel este cel din figura urmtoare este inversabil i este construit prin compunerea a dou transformri pe bii: 1) se ia inversul fa de nmulire n GF(28), elementul {00}fiind de sine stttor, 2) se aplic transformarea peste GF(2), obinndu-se noul element
(*)
pentru i = 0,7 , unde bi este al i-lea bit al octetului iar ci este al i-lea bit al octetului c de valoare {63} sau {01100011}. Forma matricii S-box folosit n funcia SubBytes() este prezentat n form hexazecimal n Fig.3 . De exemplu dac s i ,i = {53} , atunci valoarea obinut se va determina la intersecia liniei a 5 -a i a coloanei a 3-a.
2.2 Funcia ShiftRows() Aceast funcie realizeaz o deplasare ciclic a octeilor de pe ultimele trei coloane ale matricii de control, cicluri care dureaz diferit adic au offseturi diferite. Primul rnd r=0 nu este deplasat. Specific acestei transformri este operaia urmtoare: cu r = 1,3 i c = 0, Nb 1 , unde numrul de deplasri shift(r,Nb) depinde de numrul liniei r dup cum urmeaz: shift(i,4)=i , unde i = 1,3 , avnd ca efect deplasarea octeilor pe poziiile inferioare de pe linie, n timp ce octeii de pe poziiile inferioare sunt deplasai pe poziii superioare n linie, dup cum este artat n figura urmtoare:
2.3 Funcia MixColumns() n cadrul acestei transformri care opereaz cu coloanele matricii de stare, coloanele sunt considerate polinoame din GF(28) i sunt nmulire modulo x4+1 cu un polinom fixat
Ca i rezultat al acestei nmuliri, cei patru octei de pe o coloan sunt nlocuii cu:
Conform principiului algoritmului de criptare, cheia ciclic este adugat matricii de stare printr-o compunere XOR pe bii, adic fiecare cheie conine Nb cuvinte din programul cheii, cuvinte care sunt adugate coloanelor matricii de stare aa cum urmeaz unde [ w i ] sunt cuvintele din programul de cheie descris n urmtoarele seciuni, iar round este un ntreg pozitiv mai mic sau egal cu numrul de cicluri. n cadrul criptrii, primaadunare a cheii ciclice se face pentru round = 0 , mai devreme de aplicarea funciei ciclice. Aplicarea AddRoundKey() se face n ciclurile de la 1 la final. Aciunea acestei transformri este ilustrat mai jos, n Fig.7 , innd cont c l = round* Nb
2.5 Funcia de extindere a cheii Algoritmul AES preia cheia ce criptare i desfoar o ntrag rutin de extindere a acesteia pentru a genera programul cheii. Funcia de extindere a cheii genereaz un numr de Nb(Nr+1) cuvinte: algoritmul are nevoie de un set iniial de Nb cuvinte, iar fiecare dintre cele Nr cicluri are nevoie de Nb cuvinte. Programul cheii rezultat conine un ir de cuvinte pe 4 octei, notat [ w i ] , cu i = 0, Nb ( Nr + 1) 1 . Extinderea cheii de intrare n programul cheii se desfoar conform pseudo-codului de mai jos:
SubWord() este o funcie care preia un cuvnt pe patru octei de la intrare i aplic transformarea conform S-box fiecrui octet. Funcia RotWord() preia un cuvnt [a 0 a 1a 2 a 3 ] ca i intrare, execut o permutare ciclic i returneaz [a 1a 2 a 3 a 0 ] . Vectorul ciclic constant Rcon[i] conine valorile date de
// block size in 32-bit words. Always 4 for AES. (128 bits). // key size in 32-bit words. 4, 6, 8. (128, 192, 256 bits). // number of rounds. 10, 12, 14. // // // // // // the seed key. size will be 4 * keySize from ctor. Substitution box inverse Substitution box key schedule array. Round constants. State matrix
/// <summary> /// /// </summary> /// <param name="keySize"></param> /// <param name="keyBytes"></param> /// <param name="blockSize"></param> /// <returns></returns> public Aes(KeySize keySize, byte[] keyBytes, BlockSize blockSize) { BuildNaNkNr(); SetNbNkNr(keySize, blockSize); this.key = new byte[this.Nk * 4]; //keyBytes.CopyTo(this.key, 0); BuildSbox(); BuildInvSbox(); BuildRcon(); KeyExpansion(); } // Aes constructor // 16, 24, 32 bytes
public void Cipher(byte[] input, byte[] output) // encipher 16-bit input { // state = input this.State = new byte[4, Nb]; // always [4,4] for (int i = 0; i < (4 * Nb); ++i) { this.State[i % 4, i / 4] = input[i]; } AddRoundKey(0); for (int round = 1; round <= (Nr - 1); ++round) { SubBytes(); ShiftRows(); MixColumns(); AddRoundKey(round); } // main round loop SubBytes(); ShiftRows(); AddRoundKey(Nr); // main round loop
for (int i = 0; i < (4 * Nb); ++i) { output[i] = this.State[i % 4, i / 4]; } } // Cipher() // decipher 16-bit input
public void InvCipher(byte[] input, byte[] output) { // state = input this.State = new byte[4, Nb]; // always [4,4] for (int i = 0; i < (4 * Nb); ++i) { this.State[i % 4, i / 4] = input[i]; } AddRoundKey(Nr); for (int round = Nr - 1; round >= 1; --round) { InvShiftRows(); InvSubBytes(); AddRoundKey(round); InvMixColumns(); } // end main round loop for InvCipher InvShiftRows(); InvSubBytes(); AddRoundKey(0); // output = state for (int i = 0; i < (4 * Nb); ++i) { output[i] = this.State[i % 4, i / 4]; } } // InvCipher()
//BuildNaNkNr private void BuildNaNkNr() { this.NbNkNr = new int[3, 3]{ /*0 1 2*/ /*0*/ {10,12,14}, /*1*/ {12,12,14}, /*2*/ {14,14,14}}; }//BuildNaNkNr /// <summary> /// /// </summary> /// <param name="keySize"></param> /// <param name="blockSize"></param> /// <returns>void</returns> private void SetNbNkNr(KeySize keySize, BlockSize blockSize) { int x = (int)(keySize); int y = (int)(blockSize); this.Nr = NbNkNr[x, y]; if (KeySize.Bits128 == keySize) { this.Nk = 4; } else if (KeySize.Bits128 == keySize) { this.Nk = 6; } else if (KeySize.Bits256 == keySize) { this.Nk = 8; } if (BlockSize.Bits128 == blockSize) { this.Nb = 4; } else if (BlockSize.Bits128 == blockSize) { this.Nb = 6; }
/// <summary> /// /// </summary> /// <returns></returns> private void BuildSbox() { this.Sbox = new byte[16, 16] { // populate the /* 0 1 2 3 4 5 6 7 /*0*/ {0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, /*1*/ {0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, /*2*/ {0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, /*3*/ {0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, /*4*/ {0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, /*5*/ {0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, /*6*/ {0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, /*7*/ {0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, /*8*/ {0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, /*9*/ {0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, /*a*/ {0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, /*b*/ {0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, /*c*/ {0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, /*d*/ {0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, /*e*/ {0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, /*f*/ {0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, } // BuildSbox()
Sbox matrix 8 9 0x30, 0x01, 0xad, 0xd4, 0x34, 0xa5, 0x07, 0x12, 0x52, 0x3b, 0x6a, 0xcb, 0x45, 0xf9, 0xbc, 0xb6, 0xc4, 0xa7, 0x46, 0xee, 0xc2, 0xd3, 0x6c, 0x56, 0xe8, 0xdd, 0x61, 0x35, 0x9b, 0x1e, 0x41, 0x99,
a 0x67, 0xa2, 0xe5, 0x80, 0xd6, 0xbe, 0x02, 0xda, 0x7e, 0xb8, 0xac, 0xf4, 0x74, 0x57, 0x87, 0x2d,
b 0x2b, 0xaf, 0xf1, 0xe2, 0xb3, 0x39, 0x7f, 0x21, 0x3d, 0x14, 0x62, 0xea, 0x1f, 0xb9, 0xe9, 0x0f,
c 0xfe, 0x9c, 0x71, 0xeb, 0x29, 0x4a, 0x50, 0x10, 0x64, 0xde, 0x91, 0x65, 0x4b, 0x86, 0xce, 0xb0,
d 0xd7, 0xa4, 0xd8, 0x27, 0xe3, 0x4c, 0x3c, 0xff, 0x5d, 0x5e, 0x95, 0x7a, 0xbd, 0xc1, 0x55, 0x54,
e 0xab, 0x72, 0x31, 0xb2, 0x2f, 0x58, 0x9f, 0xf3, 0x19, 0x0b, 0xe4, 0xae, 0x8b, 0x1d, 0x28, 0xbb,
f */ 0x76}, 0xc0}, 0x15}, 0x75}, 0x84}, 0xcf}, 0xa8}, 0xd2}, 0x73}, 0xdb}, 0x79}, 0x08}, 0x8a}, 0x9e}, 0xdf}, 0x16} };
/// <summary> /// /// </summary> /// <returns></returns> private void BuildInvSbox() { this.iSbox = new byte[16, 16] /* 0 1 2 3 4 5 /*0*/ {0x52, 0x09, 0x6a, 0xd5, 0x30, /*1*/ {0x7c, 0xe3, 0x39, 0x82, 0x9b, /*2*/ {0x54, 0x7b, 0x94, 0x32, 0xa6, /*3*/ {0x08, 0x2e, 0xa1, 0x66, 0x28, /*4*/ {0x72, 0xf8, 0xf6, 0x64, 0x86, /*5*/ {0x6c, 0x70, 0x48, 0x50, 0xfd, /*6*/ {0x90, 0xd8, 0xab, 0x00, 0x8c, /*7*/ {0xd0, 0x2c, 0x1e, 0x8f, 0xca, /*8*/ {0x3a, 0x91, 0x11, 0x41, 0x4f, /*9*/ {0x96, 0xac, 0x74, 0x22, 0xe7, /*a*/ {0x47, 0xf1, 0x1a, 0x71, 0x1d, /*b*/ {0xfc, 0x56, 0x3e, 0x4b, 0xc6, /*c*/ {0x1f, 0xdd, 0xa8, 0x33, 0x88, /*d*/ {0x60, 0x51, 0x7f, 0xa9, 0x19, /*e*/ {0xa0, 0xe0, 0x3b, 0x4d, 0xae, /*f*/ {0x17, 0x2b, 0x04, 0x7e, 0xba, } // BuildInvSbox()
{ // 6 0x36, 0x2f, 0xc2, 0xd9, 0x68, 0xed, 0xbc, 0x3f, 0x67, 0xad, 0x29, 0xd2, 0x07, 0xb5, 0x2a, 0x77,
populate the iSbox matrix 7 8 9 a b 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0xff, 0x87, 0x34, 0x8e, 0x43, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x98, 0x16, 0xd4, 0xa4, 0x5c, 0xb9, 0xda, 0x5e, 0x15, 0x46, 0xd3, 0x0a, 0xf7, 0xe4, 0x58, 0x0f, 0x02, 0xc1, 0xaf, 0xbd, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xc5, 0x89, 0x6f, 0xb7, 0x62, 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x4a, 0x0d, 0x2d, 0xe5, 0x7a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0xd6, 0x26, 0xe1, 0x69, 0x14,
c 0x9e, 0x44, 0x0b, 0x49, 0xcc, 0x57, 0x05, 0x03, 0xce, 0xe8, 0x0e, 0xfe, 0x59, 0x9f, 0x3c, 0x63,
d 0x81, 0xc4, 0x42, 0x6d, 0x5d, 0xa7, 0xb8, 0x01, 0xf0, 0x1c, 0xaa, 0x78, 0x27, 0x93, 0x83, 0x55,
e 0xf3, 0xde, 0xfa, 0x8b, 0x65, 0x8d, 0xb3, 0x13, 0xb4, 0x75, 0x18, 0xcd, 0x80, 0xc9, 0x53, 0x21,
f */ 0xd7, 0xe9, 0xc3, 0xd1, 0xb6, 0x9d, 0x45, 0x8a, 0xe6, 0xdf, 0xbe, 0x5a, 0xec, 0x9c, 0x99, 0x0c,
0xfb}, 0xcb}, 0x4e}, 0x25}, 0x92}, 0x84}, 0x06}, 0x6b}, 0x73}, 0x6e}, 0x1b}, 0xf4}, 0x5f}, 0xef}, 0x61}, 0x7d} };
/// <summary> /// /// </summary> /// <returns></returns> private void BuildRcon() { this.Rcon = new byte[11, 4] { {0x01, {0x02, {0x04, {0x08, {0x10, {0x20, {0x40, {0x80, {0x1b, {0x36, } // BuildRcon() /// <summary> /// /// </summary>
{0x00, 0x00, 0x00, 0x00}, 0x00, 0x00, 0x00}, 0x00, 0x00, 0x00}, 0x00, 0x00, 0x00}, 0x00, 0x00, 0x00}, 0x00, 0x00, 0x00}, 0x00, 0x00, 0x00}, 0x00, 0x00, 0x00}, 0x00, 0x00, 0x00}, 0x00, 0x00, 0x00}, 0x00, 0x00, 0x00} };
/// <param name="round"></param> /// <returns></returns> private void AddRoundKey(int round) { for (int r = 0; r < 4; ++r) { for (int c = 0; c < 4; ++c) { this.State[r, c] = (byte)((int)this.State[r, c] ^ (int)w[(round * 4) + c, r]); } } // AddRoundKey()
/// <summary> /// /// </summary> /// <returns></returns> private void SubBytes() { for (int r = 0; r < 4; ++r) { for (int c = 0; c < 4; ++c) { this.State[r, c] = this.Sbox[(this.State[r, c] >> 4), (this.State[r, c] & 0x0f)]; } } } // SubBytes /// <summary> /// /// </summary> /// <returns></returns> private void InvSubBytes() { for (int r = 0; r < 4; ++r) { for (int c = 0; c < 4; ++c) { this.State[r, c] = this.iSbox[(this.State[r, c] >> 4), (this.State[r, c] & 0x0f)]; } } } // InvSubBytes /// <summary> /// /// </summary> /// <returns></returns> private void ShiftRows() { byte[,] temp = new byte[4, 4]; for (int r = 0; r < 4; ++r) // copy State into temp[] { for (int c = 0; c < 4; ++c) { temp[r, c] = this.State[r, c]; } } for (int r = 1; r < 4; ++r) // shift temp into State { for (int c = 0; c < 4; ++c) { this.State[r, c] = temp[r, (c + r) % Nb]; } } // ShiftRows()
/// <summary> /// /// </summary> /// <returns></returns> private void InvShiftRows() { byte[,] temp = new byte[4, 4]; for (int r = 0; r < 4; ++r) // copy State into temp[] { for (int c = 0; c < 4; ++c) { temp[r, c] = this.State[r, c]; } } for (int r = 1; r < 4; ++r) // shift temp into State
/// <summary> /// /// </summary> /// <returns></returns> private void MixColumns() { byte[,] temp = new byte[4, 4]; for (int r = 0; r < 4; ++r) // copy State into temp[] { for (int c = 0; c < 4; ++c) { temp[r, c] = this.State[r, c]; } } for (int c = 0; c < 4; ++c) { this.State[0, c] = (byte)((int)gfmultby02(temp[0, c]) ^ (int)gfmultby03(temp[1, c]) ^ (int)gfmultby01(temp[2, c]) ^ (int)gfmultby01(temp[3, c])); this.State[1, c] = (byte)((int)gfmultby01(temp[0, c]) ^ (int)gfmultby02(temp[1, c]) ^ (int)gfmultby03(temp[2, c]) ^ (int)gfmultby01(temp[3, c])); this.State[2, c] = (byte)((int)gfmultby01(temp[0, c]) ^ (int)gfmultby01(temp[1, c]) ^ (int)gfmultby02(temp[2, c]) ^ (int)gfmultby03(temp[3, c])); this.State[3, c] = (byte)((int)gfmultby03(temp[0, c]) ^ (int)gfmultby01(temp[1, c]) ^ (int)gfmultby01(temp[2, c]) ^ (int)gfmultby02(temp[3, c])); } // MixColumns
/// <summary> /// /// </summary> /// <returns></returns> private void InvMixColumns() { byte[,] temp = new byte[4, 4]; for (int r = 0; r < 4; ++r) // copy State into temp[] { for (int c = 0; c < 4; ++c) { temp[r, c] = this.State[r, c]; } } for (int c = 0; c < 4; ++c) { this.State[0, c] = (byte)((int)gfmultby0e(temp[0, c]) ^ (int)gfmultby0b(temp[1, c]) ^ (int)gfmultby0d(temp[2, c]) ^ (int)gfmultby09(temp[3, c])); this.State[1, c] = (byte)((int)gfmultby09(temp[0, c]) ^ (int)gfmultby0e(temp[1, c]) ^ (int)gfmultby0b(temp[2, c]) ^ (int)gfmultby0d(temp[3, c])); this.State[2, c] = (byte)((int)gfmultby0d(temp[0, c]) ^ (int)gfmultby09(temp[1, c]) ^ (int)gfmultby0e(temp[2, c]) ^ (int)gfmultby0b(temp[3, c])); this.State[3, c] = (byte)((int)gfmultby0b(temp[0, c]) ^ (int)gfmultby0d(temp[1, c]) ^ (int)gfmultby09(temp[2, c]) ^ (int)gfmultby0e(temp[3, c])); } // InvMixColumns
private static byte gfmultby01(byte b) { return b; } private static byte gfmultby02(byte b) { if (b < 0x80) return (byte)(int)(b << 1); else return (byte)((int)(b << 1) ^ (int)(0x1b)); } private static byte gfmultby03(byte b) { return (byte)((int)gfmultby02(b) ^ (int)b); } private static byte gfmultby09(byte b)
{ return (byte)((int)gfmultby02(gfmultby02(gfmultby02(b))) ^ (int)b); } private static byte gfmultby0b(byte b) { return (byte)((int)gfmultby02(gfmultby02(gfmultby02(b))) ^ (int)gfmultby02(b) ^ (int)b); } private static byte gfmultby0d(byte b) { return (byte)((int)gfmultby02(gfmultby02(gfmultby02(b))) ^ (int)gfmultby02(gfmultby02(b)) ^ (int)(b)); } private static byte gfmultby0e(byte b) { return (byte)((int)gfmultby02(gfmultby02(gfmultby02(b))) ^ (int)gfmultby02(gfmultby02(b)) ^ (int)gfmultby02(b)); } private void KeyExpansion() { this.w = new byte[Nb * (Nr + 1), 4];
for (int row = 0; row < Nk; ++row) { this.w[row, 0] = this.key[4 * row]; this.w[row, 1] = this.key[4 * row + 1]; this.w[row, 2] = this.key[4 * row + 2]; this.w[row, 3] = this.key[4 * row + 3]; } byte[] temp = new byte[4]; for (int row = Nk; row < Nb * (Nr + 1); ++row) { temp[0] = this.w[row - 1, 0]; temp[1] = this.w[row - 1, 1]; temp[2] = this.w[row - 1, 2]; temp[3] = this.w[row - 1, 3]; if (row % Nk == 0) { temp = SubWord(RotWord(temp)); temp[0] temp[1] temp[2] temp[3] = = = = (byte)((int)temp[0] (byte)((int)temp[1] (byte)((int)temp[2] (byte)((int)temp[3] ^ ^ ^ ^ (int)this.Rcon[row (int)this.Rcon[row (int)this.Rcon[row (int)this.Rcon[row / / / / Nk, Nk, Nk, Nk, 0]); 1]); 2]); 3]);
} else if (Nk > 6 && (row % Nk == 4)) { temp = SubWord(temp); } // w[row] = this.w[row, this.w[row, this.w[row, this.w[row, } } // for loop // KeyExpansion() w[row-Nk] xor temp 0] = (byte)((int)this.w[row 1] = (byte)((int)this.w[row 2] = (byte)((int)this.w[row 3] = (byte)((int)this.w[row Nk, Nk, Nk, Nk, 0] 1] 2] 3] ^ ^ ^ ^ (int)temp[0]); (int)temp[1]); (int)temp[2]); (int)temp[3]);
private byte[] SubWord(byte[] word) { byte[] result = new byte[4]; result[0] = this.Sbox[word[0] >> result[1] = this.Sbox[word[1] >> result[2] = this.Sbox[word[2] >> result[3] = this.Sbox[word[3] >> return result; } private byte[] RotWord(byte[] word) { byte[] result = new byte[4]; result[0] = word[1]; result[1] = word[2];
4, 4, 4, 4,
5. Rezultatul programului:
Concluzie AES (acronimul de la Advanced Encryption Standard - n limba englez, Standard Avansat de Criptare), cunoscut i sub numele de Rijndael, este un algoritm standardizat pentru criptarea simetric, pe blocuri, folosit astzi pe scar larg n aplicaii i adoptat ca standard de organizaia guvernamental american NIST. Standardul oficializeaz algoritmul dezvoltat de doi criptografi belgieni, Joan Daemen i Vincent Rijmen i trimis la NIST pentru selecie sub numele Rijndael.