Menu Close

Kryptologie (Praktikum 4)

Skript-AnfangKryptouebung3 – Seite 1
Skript-EndeKryptouebung3 – Seite 1

main.cpp


#include <cstdlib>
#include <iostream>
#include <iomanip>
#include "myGUI.h"


// Using-Deklarationen
using namespace std;

int main(int argc, char** argv) {
    //Start GUI
    myGUI gui;
}// main

myAES.h


#ifndef MYAES_H
#define	MYAES_H

#include <iostream>

using namespace std;
// Typedefs
typedef unsigned char uchar;

class myAES {
public:
    // Konstruktoren/Destruktoren
    myAES();
    virtual ~myAES();

    // Manuelle Eingabe
    void enterKlartext();
    void enterSchluessel();

    // Set/Get-Methoden
    void setKlartext(uchar[16]);
    void setSchluessel(uchar[16]);
    void setCiphertext(uchar[16]);
    uchar* getKlartext();
    uchar* getSchluessel();
    uchar* getCiphertext();

    // Crypt
    void crypt(bool);
    void mixcolumns();
    void shiftrows();
    void schluesselexpansion(uchar[][44], int, int, int);
    void rotword(uchar[], int);
    uchar mix(uchar, unsigned int);
    void subbytes(uchar [], uchar [], int);
    
    // Decrypt
    void decrypt(bool);
    uchar gmul(uchar, uchar);
    void invert_mixcolumns();
    void invert_shiftrows();    
    
private:
    uchar klartext[16];
    uchar schluessel[16];
    uchar ciphertext[16];
};



#endif	/* MYAES_H */

myAES.cpp


#include "myAES.h"
using namespace std;
//<editor-fold defaultstate="collapsed" desc="Boxen">
unsigned char Sbox[256] = {//  s-box
0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,
0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,
0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,
0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,
0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16
};
unsigned char sbox_inverse[256] = {
0x52, 0x09, 0x6A, 0xD5, 0x30, 0x36, 0xA5, 0x38, 0xBF, 0x40, 0xA3, 0x9E, 0x81, 0xF3, 0xD7, 0xFB,
0x7C, 0xE3, 0x39, 0x82, 0x9B, 0x2F, 0xFF, 0x87, 0x34, 0x8E, 0x43, 0x44, 0xC4, 0xDE, 0xE9, 0xCB,
0x54, 0x7B, 0x94, 0x32, 0xA6, 0xC2, 0x23, 0x3D, 0xEE, 0x4C, 0x95, 0x0B, 0x42, 0xFA, 0xC3, 0x4E,
0x08, 0x2E, 0xA1, 0x66, 0x28, 0xD9, 0x24, 0xB2, 0x76, 0x5B, 0xA2, 0x49, 0x6D, 0x8B, 0xD1, 0x25,
0x72, 0xF8, 0xF6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xD4, 0xA4, 0x5C, 0xCC, 0x5D, 0x65, 0xB6, 0x92,
0x6C, 0x70, 0x48, 0x50, 0xFD, 0xED, 0xB9, 0xDA, 0x5E, 0x15, 0x46, 0x57, 0xA7, 0x8D, 0x9D, 0x84,
0x90, 0xD8, 0xAB, 0x00, 0x8C, 0xBC, 0xD3, 0x0A, 0xF7, 0xE4, 0x58, 0x05, 0xB8, 0xB3, 0x45, 0x06,
0xD0, 0x2C, 0x1E, 0x8F, 0xCA, 0x3F, 0x0F, 0x02, 0xC1, 0xAF, 0xBD, 0x03, 0x01, 0x13, 0x8A, 0x6B,
0x3A, 0x91, 0x11, 0x41, 0x4F, 0x67, 0xDC, 0xEA, 0x97, 0xF2, 0xCF, 0xCE, 0xF0, 0xB4, 0xE6, 0x73,
0x96, 0xAC, 0x74, 0x22, 0xE7, 0xAD, 0x35, 0x85, 0xE2, 0xF9, 0x37, 0xE8, 0x1C, 0x75, 0xDF, 0x6E,
0x47, 0xF1, 0x1A, 0x71, 0x1D, 0x29, 0xC5, 0x89, 0x6F, 0xB7, 0x62, 0x0E, 0xAA, 0x18, 0xBE, 0x1B,
0xFC, 0x56, 0x3E, 0x4B, 0xC6, 0xD2, 0x79, 0x20, 0x9A, 0xDB, 0xC0, 0xFE, 0x78, 0xCD, 0x5A, 0xF4,
0x1F, 0xDD, 0xA8, 0x33, 0x88, 0x07, 0xC7, 0x31, 0xB1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xEC, 0x5F,
0x60, 0x51, 0x7F, 0xA9, 0x19, 0xB5, 0x4A, 0x0D, 0x2D, 0xE5, 0x7A, 0x9F, 0x93, 0xC9, 0x9C, 0xEF,
0xA0, 0xE0, 0x3B, 0x4D, 0xAE, 0x2A, 0xF5, 0xB0, 0xC8, 0xEB, 0xBB, 0x3C, 0x83, 0x53, 0x99, 0x61,
0x17, 0x2B, 0x04, 0x7E, 0xBA, 0x77, 0xD6, 0x26, 0xE1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0C, 0x7D
};
unsigned char Rcon[256] = {
0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a,
0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39,
0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a,
0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8,
0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef,
0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc,
0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b,
0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3,
0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94,
0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20,
0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35,
0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f,
0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04,
0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63,
0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd,
0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d
};
//</editor-fold>
//<editor-fold defaultstate="collapsed" desc="AES-Methoden">
void myAES::subbytes(uchar sbox[], uchar tmp[], int arrSize) {
for (int i = 0; i < arrSize; i++) {
tmp[i] = sbox[tmp[i]];
}
}// subbytes
uchar myAES::mix(uchar byte, unsigned int mixvalue) {
unsigned char retValue;
switch (mixvalue) {
case 1:
retValue = byte;
break;
case 2:
retValue = byte << 1;
if (byte & 0x80) {
retValue = retValue ^ 0x1b;
}
break;
case 3:
retValue = byte << 1;
if (byte & 0x80) {
retValue = retValue ^ 0x1b;
}
retValue = retValue^byte;
break;
}
return retValue;
}
void addRoundKey(uchar array[], uchar matrix[][44], int iReihe, int iSpalte, int iRunde) {
int pos = 0;
for (int i = iRunde * 4; i < ((iRunde * 4) + 4) && i < iSpalte; i++) {
for (int k = 0; k < iReihe; k++) {
array[pos] = array[pos] ^ matrix[k][i];
pos++;
}
}
}// addroundkey
void myAES::rotword(uchar column[], int iReihe) {
uchar tmp = column[0];
for (int i = 1; i < iReihe; i++) {
column[i - 1] = column[i];
}
column[iReihe - 1] = tmp;
} // rotword
void myAES::schluesselexpansion(uchar matrix[][44], int iReihe, int iSpalte, int iLaenge) {
// Alle Spalten durchlaufen
int pos = 0;
for (int i = 0; i < iSpalte; i++) {
if (i < 4) { // Schluessel in erste vier Spalten kopieren
for (int k = 0; k < iReihe && pos < iLaenge; k++) {
matrix[k][i] = schluessel[pos];
pos++;
//cout << hex << "matrix[" << k << "][" << i << "] = " << (int) matrix[k][i] << endl;
}
} else { // i > 4
if (i % 4 == 0) {// erste Spalte eines Schluessels
// Spalte in Hilfsarray kopieren
uchar tmp[iReihe]; // i-1
uchar tmp2[iReihe]; // i-4
for (int k = 0; k < iReihe; k++) {
tmp[k] = matrix[k][i - 1];
tmp2[k] = matrix[k][i - 4];
}
rotword(tmp, iReihe);
subbytes(Sbox, tmp, iReihe);
// Spalte[i-4] XOR subbytes[rotword[i-i]
for (int k = 0; k < iReihe; k++) {
tmp[k] = tmp[k] ^ tmp2[k];
}
// tmp[0] XOR (i/4)
tmp[0] = tmp[0] ^ Rcon[i / iReihe];
// tmp[k] an Spalte[k][i] kopieren
for (int k = 0; k < iReihe; k++) {
matrix[k][i] = tmp[k];
}
} else {
//cout << "i " << i << endl;
for (int k = 0; k < iReihe; k++) {
matrix[k][i] = matrix[k][i - 4] ^ matrix[k][i - 1];
}
}
}
}
}// schluesselexpansion
void myAES::shiftrows() {
uchar copys[16] = {};
//reihe 1   
copys[0] = ciphertext[0];
copys[4] = ciphertext[4];
copys[8] = ciphertext[8];
copys[12] = ciphertext[12];
//reihe 2
copys[1] = ciphertext[5];
copys[5] = ciphertext[9];
copys[9] = ciphertext[13];
copys[13] = ciphertext[1];
// reihe 3
copys[2] = ciphertext[10];
copys[6] = ciphertext[14];
copys[10] = ciphertext[2];
copys[14] = ciphertext[6];
//reihe 4
copys[3] = ciphertext[15];
copys[7] = ciphertext[3];
copys[11] = ciphertext[7];
copys[15] = ciphertext[11];
//umschreiben   
for (int i = 0; i < 16; i++) {
ciphertext[i] = copys[i];
}
}// shiftrows
void myAES::mixcolumns() {
for (int i = 0; i < 4; i++) {
uchar sj0 = mix(ciphertext[i * 4], 2)^mix(ciphertext[i * 4 + 1], 3)^mix(ciphertext[i * 4 + 2], 1)^mix(ciphertext[i * 4 + 3], 1);
uchar sj1 = mix(ciphertext[i * 4], 1)^mix(ciphertext[i * 4 + 1], 2)^mix(ciphertext[i * 4 + 2], 3)^mix(ciphertext[i * 4 + 3], 1);
uchar sj2 = mix(ciphertext[i * 4], 1)^mix(ciphertext[i * 4 + 1], 1)^mix(ciphertext[i * 4 + 2], 2)^mix(ciphertext[i * 4 + 3], 3);
uchar sj3 = mix(ciphertext[i * 4], 3)^mix(ciphertext[i * 4 + 1], 1)^mix(ciphertext[i * 4 + 2], 1)^mix(ciphertext[i * 4 + 3], 2);
ciphertext[i * 4] = sj0;
ciphertext[i * 4 + 1] = sj1;
ciphertext[i * 4 + 2] = sj2;
ciphertext[i * 4 + 3] = sj3;
}
}// mixcolumns
void myAES::crypt(bool output) {
// Parameter
int iRunde = 10;
int iLaenge = 16;
// Überschreibe ciphertext um diesen fortan zu verwenden
for (int i = 0; i < 16; i++) {
ciphertext[i] = klartext[i];
}
// Arraygroesse dynamisch bestimmen
int arrSize = sizeof (ciphertext) / sizeof (ciphertext[0]);
// Zwischenspeicherung der Rundenschluessel
int iReihe = 4;
int iSpalte = 4 * (iRunde + 1);
uchar carrRundenschluessel[4][44];
// Schluessel expandieren
schluesselexpansion(carrRundenschluessel, iReihe, iSpalte, iLaenge);
// Vorrunde
for (int k = 0; k < iLaenge; k++) {
ciphertext[k] = ciphertext[k] ^ schluessel[k];
}
// Durchlaufen der Runden
for (int i = 1; i < iRunde + 1; i++) {
// S-Box
subbytes(Sbox, ciphertext, arrSize);
// Shift Rows
shiftrows();
// Mix Columns
if (i != (iRunde)) { // kein MixColumns in der letzten Runde
mixcolumns();
}
// Rundenschlüssel addieren
addRoundKey(ciphertext, carrRundenschluessel, iReihe, iSpalte, i);
}
}
void myAES::invert_shiftrows() {
uchar copys[16] = {};
//reihe 1   
copys[0] = klartext[0];
copys[4] = klartext[4];
copys[8] = klartext[8];
copys[12] = klartext[12];
//reihe 2
copys[1] = klartext[13];
copys[13] = klartext[9];
copys[9] = klartext[5];
copys[5] = klartext[1];
// reihe 3   
copys[6] = klartext[14];
copys[2] = klartext[10];
copys[14] = klartext[6];
copys[10] = klartext[2];
//reihe 4
copys[11] = klartext[15];
copys[7] = klartext[11];
copys[3] = klartext[7];
copys[15] = klartext[3];
//umschreiben   
for (int i = 0; i < 16; i++) {
klartext[i] = copys[i];
}
}// invert_shiftrows
void myAES::invert_mixcolumns() {
for (int i = 0; i < 4; i++) {
uchar sj0 = gmul(klartext[i * 4], 14)^gmul(klartext[i * 4 + 1], 11)^gmul(klartext[i * 4 + 2], 13)^gmul(klartext[i * 4 + 3], 9);
uchar sj1 = gmul(klartext[i * 4], 9)^gmul(klartext[i * 4 + 1], 14)^gmul(klartext[i * 4 + 2], 11)^gmul(klartext[i * 4 + 3], 13);
uchar sj2 = gmul(klartext[i * 4], 13)^gmul(klartext[i * 4 + 1], 9)^gmul(klartext[i * 4 + 2], 14)^gmul(klartext[i * 4 + 3], 11);
uchar sj3 = gmul(klartext[i * 4], 11)^gmul(klartext[i * 4 + 1], 13)^gmul(klartext[i * 4 + 2], 9)^gmul(klartext[i * 4 + 3], 14);
klartext[i * 4] = sj0;
klartext[i * 4 + 1] = sj1;
klartext[i * 4 + 2] = sj2;
klartext[i * 4 + 3] = sj3;
}
}
uchar myAES::gmul(uchar a, uchar b) {
unsigned char p = 0;
unsigned char hi;
for (int i = 0; i < 8; ++i) {
if ((b & 1) == 1)
p ^= a;
hi = (a & 0x80);
a <<= 1;
if (hi == 0x80)
a ^= 0x1b;
b >>= 1;
}
return p;
}
void myAES::decrypt(bool output) {
// Parameter
int iRunde = 10;
int iLaenge = 16;
// Überschreibe klartext um diesen fortan zu verwenden
for (int i = 0; i < 16; i++) {
klartext[i] = ciphertext[i];
}
// Arraygroesse dynamisch bestimmen
int arrSize = sizeof (klartext) / sizeof (klartext[0]);
// Zwischenspeicherung der Rundenschluessel
int iReihe = 4;
int iSpalte = 4 * (iRunde + 1);
uchar carrRundenschluessel[4][44];
// Schluessel expandieren
schluesselexpansion(carrRundenschluessel, iReihe, iSpalte, iLaenge);
// "neue" Vorrunde
addRoundKey(klartext, carrRundenschluessel, iReihe, iSpalte, 10);
// Durchlaufen der Runden
for (int i = 9; i > 0; i--) {
// Shift Rows
invert_shiftrows();
// S-Box
subbytes(sbox_inverse, klartext, arrSize);
// Rundenschlüssel addieren
addRoundKey(klartext, carrRundenschluessel, iReihe, iSpalte, i);
// Mix Columns
if (i != 10) { // kein MixColumns in der letzten Runde
invert_mixcolumns();
}
}
// Letzte Runde
invert_shiftrows();
subbytes(sbox_inverse, klartext, arrSize);
for (int k = 0; k < iLaenge; k++) {
klartext[k] = klartext[k] ^ schluessel[k];
}
}// decrypt
//</editor-fold>
//<editor-fold defaultstate="collapsed" desc="Konstruktur/Destruktor">
myAES::myAES() {
uchar kt[16] = {0x61, 0x62, 0x62, 0x69, 0x6c, 0x64, 0x75, 0x6e, 0x67, 0x73, 0x6d, 0x61, 0x74, 0x72, 0x69, 0x78};
uchar s[16] = {0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31};
//uchar c[16] = {0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31};
for (int i = 0; i < 16; i++) {
schluessel[i] = s[i];
klartext[i] = kt[i];
}
}
myAES::~myAES() {
}
//</editor-fold>
//<editor-fold defaultstate="collapsed" desc="Manuelle Eingabe">
void enterValues(uchar arr[], string name) {
string tmp = "";
int diff = 0;
cout << name << ": (16 Zeichen):";
if (cin >> tmp) {
if (tmp.length() > 16) {
cerr << "\nWerte fuer den" << name << " zu groß. Trenne nach 16 Zeichen ab.\n(";
for (int i = 0; i < tmp.length(); i++) {
if (i == 16) {
cerr << " | ";
}
cerr << tmp.at(i);
}
cout << ")" << endl;
}
if (tmp.length() < 16) {
cerr << "\nWert fuer den Klartext zu klein. Fuelle mit Nullen auf.\n";
diff = 16 - tmp.length();
for (int i = 0; i < diff; i++) {
tmp.push_back('
Menu Close

Kryptologie (Praktikum 4)

Skript-AnfangKryptouebung3 – Seite 1
Skript-EndeKryptouebung3 – Seite 1

main.cpp


#include <cstdlib>
#include <iostream>
#include <iomanip>
#include "myGUI.h"


// Using-Deklarationen
using namespace std;

int main(int argc, char** argv) {
    //Start GUI
    myGUI gui;
}// main

myAES.h


#ifndef MYAES_H
#define	MYAES_H

#include <iostream>

using namespace std;
// Typedefs
typedef unsigned char uchar;

class myAES {
public:
    // Konstruktoren/Destruktoren
    myAES();
    virtual ~myAES();

    // Manuelle Eingabe
    void enterKlartext();
    void enterSchluessel();

    // Set/Get-Methoden
    void setKlartext(uchar[16]);
    void setSchluessel(uchar[16]);
    void setCiphertext(uchar[16]);
    uchar* getKlartext();
    uchar* getSchluessel();
    uchar* getCiphertext();

    // Crypt
    void crypt(bool);
    void mixcolumns();
    void shiftrows();
    void schluesselexpansion(uchar[][44], int, int, int);
    void rotword(uchar[], int);
    uchar mix(uchar, unsigned int);
    void subbytes(uchar [], uchar [], int);
    
    // Decrypt
    void decrypt(bool);
    uchar gmul(uchar, uchar);
    void invert_mixcolumns();
    void invert_shiftrows();    
    
private:
    uchar klartext[16];
    uchar schluessel[16];
    uchar ciphertext[16];
};



#endif	/* MYAES_H */

myAES.cpp


#include "myAES.h"

using namespace std;

//<editor-fold defaultstate="collapsed" desc="Boxen">

unsigned char Sbox[256] = {//  s-box
    0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
    0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
    0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
    0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
    0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,
    0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
    0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,
    0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,
    0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
    0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
    0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,
    0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
    0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
    0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
    0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
    0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16
};

unsigned char sbox_inverse[256] = {
    0x52, 0x09, 0x6A, 0xD5, 0x30, 0x36, 0xA5, 0x38, 0xBF, 0x40, 0xA3, 0x9E, 0x81, 0xF3, 0xD7, 0xFB,
    0x7C, 0xE3, 0x39, 0x82, 0x9B, 0x2F, 0xFF, 0x87, 0x34, 0x8E, 0x43, 0x44, 0xC4, 0xDE, 0xE9, 0xCB,
    0x54, 0x7B, 0x94, 0x32, 0xA6, 0xC2, 0x23, 0x3D, 0xEE, 0x4C, 0x95, 0x0B, 0x42, 0xFA, 0xC3, 0x4E,
    0x08, 0x2E, 0xA1, 0x66, 0x28, 0xD9, 0x24, 0xB2, 0x76, 0x5B, 0xA2, 0x49, 0x6D, 0x8B, 0xD1, 0x25,
    0x72, 0xF8, 0xF6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xD4, 0xA4, 0x5C, 0xCC, 0x5D, 0x65, 0xB6, 0x92,
    0x6C, 0x70, 0x48, 0x50, 0xFD, 0xED, 0xB9, 0xDA, 0x5E, 0x15, 0x46, 0x57, 0xA7, 0x8D, 0x9D, 0x84,
    0x90, 0xD8, 0xAB, 0x00, 0x8C, 0xBC, 0xD3, 0x0A, 0xF7, 0xE4, 0x58, 0x05, 0xB8, 0xB3, 0x45, 0x06,
    0xD0, 0x2C, 0x1E, 0x8F, 0xCA, 0x3F, 0x0F, 0x02, 0xC1, 0xAF, 0xBD, 0x03, 0x01, 0x13, 0x8A, 0x6B,
    0x3A, 0x91, 0x11, 0x41, 0x4F, 0x67, 0xDC, 0xEA, 0x97, 0xF2, 0xCF, 0xCE, 0xF0, 0xB4, 0xE6, 0x73,
    0x96, 0xAC, 0x74, 0x22, 0xE7, 0xAD, 0x35, 0x85, 0xE2, 0xF9, 0x37, 0xE8, 0x1C, 0x75, 0xDF, 0x6E,
    0x47, 0xF1, 0x1A, 0x71, 0x1D, 0x29, 0xC5, 0x89, 0x6F, 0xB7, 0x62, 0x0E, 0xAA, 0x18, 0xBE, 0x1B,
    0xFC, 0x56, 0x3E, 0x4B, 0xC6, 0xD2, 0x79, 0x20, 0x9A, 0xDB, 0xC0, 0xFE, 0x78, 0xCD, 0x5A, 0xF4,
    0x1F, 0xDD, 0xA8, 0x33, 0x88, 0x07, 0xC7, 0x31, 0xB1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xEC, 0x5F,
    0x60, 0x51, 0x7F, 0xA9, 0x19, 0xB5, 0x4A, 0x0D, 0x2D, 0xE5, 0x7A, 0x9F, 0x93, 0xC9, 0x9C, 0xEF,
    0xA0, 0xE0, 0x3B, 0x4D, 0xAE, 0x2A, 0xF5, 0xB0, 0xC8, 0xEB, 0xBB, 0x3C, 0x83, 0x53, 0x99, 0x61,
    0x17, 0x2B, 0x04, 0x7E, 0xBA, 0x77, 0xD6, 0x26, 0xE1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0C, 0x7D
};

unsigned char Rcon[256] = {
    0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a,
    0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39,
    0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a,
    0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8,
    0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef,
    0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc,
    0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b,
    0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3,
    0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94,
    0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20,
    0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35,
    0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f,
    0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04,
    0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63,
    0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd,
    0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d
};
//</editor-fold>

//<editor-fold defaultstate="collapsed" desc="AES-Methoden">

void myAES::subbytes(uchar sbox[], uchar tmp[], int arrSize) {
    for (int i = 0; i < arrSize; i++) {
        tmp[i] = sbox[tmp[i]];
    }
}// subbytes

uchar myAES::mix(uchar byte, unsigned int mixvalue) {
    unsigned char retValue;
    switch (mixvalue) {
        case 1:
            retValue = byte;
            break;
        case 2:
            retValue = byte << 1;
            if (byte & 0x80) {
                retValue = retValue ^ 0x1b;
            }
            break;
        case 3:
            retValue = byte << 1;
            if (byte & 0x80) {
                retValue = retValue ^ 0x1b;
            }
            retValue = retValue^byte;
            break;
    }
    return retValue;
}

void addRoundKey(uchar array[], uchar matrix[][44], int iReihe, int iSpalte, int iRunde) {
    int pos = 0;
    for (int i = iRunde * 4; i < ((iRunde * 4) + 4) && i < iSpalte; i++) {
        for (int k = 0; k < iReihe; k++) {
            array[pos] = array[pos] ^ matrix[k][i];
            pos++;
        }
    }
}// addroundkey

void myAES::rotword(uchar column[], int iReihe) {
    uchar tmp = column[0];
    for (int i = 1; i < iReihe; i++) {
        column[i - 1] = column[i];
    }
    column[iReihe - 1] = tmp;
} // rotword

void myAES::schluesselexpansion(uchar matrix[][44], int iReihe, int iSpalte, int iLaenge) {
    // Alle Spalten durchlaufen
    int pos = 0;

    for (int i = 0; i < iSpalte; i++) {
        if (i < 4) { // Schluessel in erste vier Spalten kopieren
            for (int k = 0; k < iReihe && pos < iLaenge; k++) {
                matrix[k][i] = schluessel[pos];
                pos++;
                //cout << hex << "matrix[" << k << "][" << i << "] = " << (int) matrix[k][i] << endl;
            }
        } else { // i > 4
            if (i % 4 == 0) {// erste Spalte eines Schluessels
                // Spalte in Hilfsarray kopieren
                uchar tmp[iReihe]; // i-1
                uchar tmp2[iReihe]; // i-4
                for (int k = 0; k < iReihe; k++) {
                    tmp[k] = matrix[k][i - 1];
                    tmp2[k] = matrix[k][i - 4];
                }

                rotword(tmp, iReihe);

                subbytes(Sbox, tmp, iReihe);

                // Spalte[i-4] XOR subbytes[rotword[i-i]
                for (int k = 0; k < iReihe; k++) {
                    tmp[k] = tmp[k] ^ tmp2[k];
                }

                // tmp[0] XOR (i/4)
                tmp[0] = tmp[0] ^ Rcon[i / iReihe];

                // tmp[k] an Spalte[k][i] kopieren
                for (int k = 0; k < iReihe; k++) {
                    matrix[k][i] = tmp[k];
                }

            } else {
                //cout << "i " << i << endl;
                for (int k = 0; k < iReihe; k++) {
                    matrix[k][i] = matrix[k][i - 4] ^ matrix[k][i - 1];
                }
            }
        }
    }
}// schluesselexpansion

void myAES::shiftrows() {
    uchar copys[16] = {};

    //reihe 1   
    copys[0] = ciphertext[0];
    copys[4] = ciphertext[4];
    copys[8] = ciphertext[8];
    copys[12] = ciphertext[12];

    //reihe 2
    copys[1] = ciphertext[5];
    copys[5] = ciphertext[9];
    copys[9] = ciphertext[13];
    copys[13] = ciphertext[1];

    // reihe 3
    copys[2] = ciphertext[10];
    copys[6] = ciphertext[14];
    copys[10] = ciphertext[2];
    copys[14] = ciphertext[6];

    //reihe 4
    copys[3] = ciphertext[15];
    copys[7] = ciphertext[3];
    copys[11] = ciphertext[7];
    copys[15] = ciphertext[11];

    //umschreiben   
    for (int i = 0; i < 16; i++) {
        ciphertext[i] = copys[i];
    }
}// shiftrows

void myAES::mixcolumns() {
    for (int i = 0; i < 4; i++) {
        uchar sj0 = mix(ciphertext[i * 4], 2)^mix(ciphertext[i * 4 + 1], 3)^mix(ciphertext[i * 4 + 2], 1)^mix(ciphertext[i * 4 + 3], 1);
        uchar sj1 = mix(ciphertext[i * 4], 1)^mix(ciphertext[i * 4 + 1], 2)^mix(ciphertext[i * 4 + 2], 3)^mix(ciphertext[i * 4 + 3], 1);
        uchar sj2 = mix(ciphertext[i * 4], 1)^mix(ciphertext[i * 4 + 1], 1)^mix(ciphertext[i * 4 + 2], 2)^mix(ciphertext[i * 4 + 3], 3);
        uchar sj3 = mix(ciphertext[i * 4], 3)^mix(ciphertext[i * 4 + 1], 1)^mix(ciphertext[i * 4 + 2], 1)^mix(ciphertext[i * 4 + 3], 2);
        ciphertext[i * 4] = sj0;
        ciphertext[i * 4 + 1] = sj1;
        ciphertext[i * 4 + 2] = sj2;
        ciphertext[i * 4 + 3] = sj3;
    }
}// mixcolumns

void myAES::crypt(bool output) {

    // Parameter
    int iRunde = 10;
    int iLaenge = 16;

    // Überschreibe ciphertext um diesen fortan zu verwenden
    for (int i = 0; i < 16; i++) {
        ciphertext[i] = klartext[i];
    }

    // Arraygroesse dynamisch bestimmen
    int arrSize = sizeof (ciphertext) / sizeof (ciphertext[0]);

    // Zwischenspeicherung der Rundenschluessel
    int iReihe = 4;
    int iSpalte = 4 * (iRunde + 1);
    uchar carrRundenschluessel[4][44];

    // Schluessel expandieren
    schluesselexpansion(carrRundenschluessel, iReihe, iSpalte, iLaenge);

    // Vorrunde
    for (int k = 0; k < iLaenge; k++) {
        ciphertext[k] = ciphertext[k] ^ schluessel[k];
    }

    // Durchlaufen der Runden
    for (int i = 1; i < iRunde + 1; i++) {

        // S-Box
        subbytes(Sbox, ciphertext, arrSize);

        // Shift Rows
        shiftrows();

        // Mix Columns
        if (i != (iRunde)) { // kein MixColumns in der letzten Runde
            mixcolumns();
        }

        // Rundenschlüssel addieren
        addRoundKey(ciphertext, carrRundenschluessel, iReihe, iSpalte, i);

    }
}

void myAES::invert_shiftrows() {
    uchar copys[16] = {};

    //reihe 1   
    copys[0] = klartext[0];
    copys[4] = klartext[4];
    copys[8] = klartext[8];
    copys[12] = klartext[12];

    //reihe 2
    copys[1] = klartext[13];
    copys[13] = klartext[9];
    copys[9] = klartext[5];
    copys[5] = klartext[1];

    // reihe 3   
    copys[6] = klartext[14];
    copys[2] = klartext[10];
    copys[14] = klartext[6];
    copys[10] = klartext[2];

    //reihe 4
    copys[11] = klartext[15];
    copys[7] = klartext[11];
    copys[3] = klartext[7];
    copys[15] = klartext[3];

    //umschreiben   
    for (int i = 0; i < 16; i++) {
        klartext[i] = copys[i];
    }
}// invert_shiftrows

void myAES::invert_mixcolumns() {
    for (int i = 0; i < 4; i++) {
        uchar sj0 = gmul(klartext[i * 4], 14)^gmul(klartext[i * 4 + 1], 11)^gmul(klartext[i * 4 + 2], 13)^gmul(klartext[i * 4 + 3], 9);
        uchar sj1 = gmul(klartext[i * 4], 9)^gmul(klartext[i * 4 + 1], 14)^gmul(klartext[i * 4 + 2], 11)^gmul(klartext[i * 4 + 3], 13);
        uchar sj2 = gmul(klartext[i * 4], 13)^gmul(klartext[i * 4 + 1], 9)^gmul(klartext[i * 4 + 2], 14)^gmul(klartext[i * 4 + 3], 11);
        uchar sj3 = gmul(klartext[i * 4], 11)^gmul(klartext[i * 4 + 1], 13)^gmul(klartext[i * 4 + 2], 9)^gmul(klartext[i * 4 + 3], 14);
        klartext[i * 4] = sj0;
        klartext[i * 4 + 1] = sj1;
        klartext[i * 4 + 2] = sj2;
        klartext[i * 4 + 3] = sj3;
    }
}

uchar myAES::gmul(uchar a, uchar b) {
    unsigned char p = 0;
    unsigned char hi;

    for (int i = 0; i < 8; ++i) {
        if ((b & 1) == 1)
            p ^= a;
        hi = (a & 0x80);
        a <<= 1;
        if (hi == 0x80)
            a ^= 0x1b;
        b >>= 1;
    }
    return p;
}

void myAES::decrypt(bool output) {

    // Parameter
    int iRunde = 10;
    int iLaenge = 16;


    // Überschreibe klartext um diesen fortan zu verwenden
    for (int i = 0; i < 16; i++) {
        klartext[i] = ciphertext[i];
    }

    // Arraygroesse dynamisch bestimmen
    int arrSize = sizeof (klartext) / sizeof (klartext[0]);

    // Zwischenspeicherung der Rundenschluessel
    int iReihe = 4;
    int iSpalte = 4 * (iRunde + 1);
    uchar carrRundenschluessel[4][44];

    // Schluessel expandieren
    schluesselexpansion(carrRundenschluessel, iReihe, iSpalte, iLaenge);

    // "neue" Vorrunde
    addRoundKey(klartext, carrRundenschluessel, iReihe, iSpalte, 10);

    // Durchlaufen der Runden
    for (int i = 9; i > 0; i--) {

        // Shift Rows
        invert_shiftrows();

        // S-Box
        subbytes(sbox_inverse, klartext, arrSize);

        // Rundenschlüssel addieren
        addRoundKey(klartext, carrRundenschluessel, iReihe, iSpalte, i);

        // Mix Columns
        if (i != 10) { // kein MixColumns in der letzten Runde
            invert_mixcolumns();
        }
    }

    // Letzte Runde
    invert_shiftrows();
    subbytes(sbox_inverse, klartext, arrSize);

    for (int k = 0; k < iLaenge; k++) {
        klartext[k] = klartext[k] ^ schluessel[k];
    }
}// decrypt

//</editor-fold>

//<editor-fold defaultstate="collapsed" desc="Konstruktur/Destruktor">

myAES::myAES() {
    uchar kt[16] = {0x61, 0x62, 0x62, 0x69, 0x6c, 0x64, 0x75, 0x6e, 0x67, 0x73, 0x6d, 0x61, 0x74, 0x72, 0x69, 0x78};
    uchar s[16] = {0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31};
    //uchar c[16] = {0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31};
    for (int i = 0; i < 16; i++) {
        schluessel[i] = s[i];
        klartext[i] = kt[i];
    }
}

myAES::~myAES() {
}
//</editor-fold>

//<editor-fold defaultstate="collapsed" desc="Manuelle Eingabe">

void enterValues(uchar arr[], string name) {
    string tmp = "";
    int diff = 0;
    cout << name << ": (16 Zeichen):";
    if (cin >> tmp) {

        if (tmp.length() > 16) {
            cerr << "\nWerte fuer den" << name << " zu groß. Trenne nach 16 Zeichen ab.\n(";
            for (int i = 0; i < tmp.length(); i++) {
                if (i == 16) {
                    cerr << " | ";
                }
                cerr << tmp.at(i);
            }
            cout << ")" << endl;
        }

        if (tmp.length() < 16) {
            cerr << "\nWert fuer den Klartext zu klein. Fuelle mit Nullen auf.\n";
            diff = 16 - tmp.length();
            for (int i = 0; i < diff; i++) {
                tmp.push_back('\0');
            }
            cout << endl;
        }

        for (int i = 0; i < 16; i++) {
            arr[i] = tmp[i];
        }
        cout << endl;

    }
}

void myAES::enterKlartext() {
    enterValues(klartext, "Klartext");
}

void myAES::enterSchluessel() {
    enterValues(schluessel, "Schluessel");
}

//</editor-fold>

//<editor-fold defaultstate="collapsed" desc="Set/Get-Methoden">

void myAES::setCiphertext(uchar tmp[16]) {
    for (int i = 0; i < 16; i++) {
        ciphertext[i] = tmp[i];
    }
}

void myAES::setKlartext(uchar tmp[16]) {
    for (int i = 0; i < 16; i++) {
        klartext[i] = tmp[i];
    }
}

void myAES::setSchluessel(uchar tmp[16]) {
    for (int i = 0; i < 16; i++) {
        schluessel[i] = tmp[i];
    }
}

uchar* myAES::getSchluessel() {
    return schluessel;
}

uchar* myAES::getCiphertext() {
    return ciphertext;
}

uchar* myAES::getKlartext() {
    return klartext;
}

//</editor-fold>

myCBC.h


#ifndef MYCBC_H
#define	MYCBC_H
#include "myAES.h"
#include <vector>
class myCBC {
public:
    // Konstruktoren / Destruktoren
    myCBC();
    virtual ~myCBC();
    
    //CBC
    void crypt(bool);
    void decrypt(bool);
    
    // Set/Get-Methoden
    void setKey(uchar[16]);
    void setIV(uchar[16]);
    void setKlartext(vector<uchar>);
    void setCiphertext(vector<uchar>);
    vector<uchar> getKlartext();
    vector<uchar> getCiphertext();
    uchar* getSchluessel();
    uchar* getIV();
    
    // Manuelle Eingabe
    void enterKey();
    void enterIV();
    void enterKlartext();
    
private:
    uchar iv[16];
    uchar key[16];
    vector<uchar> klartext;
    vector<uchar> ciphertext;
};

myCBC.cpp


#include "myCBC.h"
#include <math.h>
#include <iostream>
#include <iomanip>

using namespace std;

uchar* myCBC::getSchluessel() {
    return key;
}

vector<uchar> myCBC::getKlartext() {
    return klartext;
}

void enterValue(uchar arr[], string name) {
    string tmp = "";
    int diff = 0;
    cout << name << ": (16 Zeichen):";
    if (cin >> tmp) {

        if (tmp.length() > 16) {
            cerr << "\nWerte fuer den" << name << " zu groß. Trenne nach 16 Zeichen ab.\n(";
            for (int i = 0; i < tmp.length(); i++) {
                if (i == 16) {
                    cerr << " | ";
                }
                cerr << tmp.at(i);
            }
            cout << ")" << endl;
        }

        if (tmp.length() < 16) {
            cerr << "\nWert fuer den Klartext zu klein. Fuelle mit Nullen auf.\n";
            diff = 16 - tmp.length();
            for (int i = 0; i < diff; i++) {
                tmp.push_back('\0');
            }
            cout << endl;
        }

        for (int i = 0; i < 16; i++) {
            arr[i] = tmp[i];
        }
        cout << endl;

    }
}

void myCBC::enterKey() {
    enterValue(key, "Schluessel");
}

void myCBC::enterIV() {
    enterValue(iv, "Initialisierungsvektor");
}

void myCBC::enterKlartext() {
    klartext.clear();
    string tmp = "";
    cout << "Klartext (Beliebig viele Zeichen):";
    if (cin >> tmp) {
        for (int i = 0; i < tmp.size(); i++) {
            klartext.push_back(tmp[i]);
        }
        cout << endl;
    }

    if (tmp.size() % 16 != 0) {
        cerr << "\nLetzter Klartext-Block nicht vollstaendig. Fuelle mit Nullen auf.\n";
        for (int i = 0; i < 16 - tmp.size() % 16; i++) {
            klartext.push_back('\0');
        }
        cout << endl;
    }
}

myCBC::myCBC() {

    // Default Parameter
    uchar newKey[16] = {0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c};
    uchar newIV[16] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F};
    uchar newKlartext[16] = {0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a};

    // Schluessel setzen
    for (int i = 0; i < 16; i++) {
        key[i] = newKey[i];
    }

    //IV setzen
    for (int i = 0; i < 16; i++) {
        iv[i] = newIV[i];
    }

    // Klartext setzen
    for (int i = 0; i < 16; i++) {
        klartext.push_back(newKlartext[i]);
    }
}

vector<uchar> myCBC::getCiphertext() {
    return ciphertext;
}

void myCBC::decrypt(bool print) {
    klartext.clear();

    uchar tmp_iv[16];
    for (int j = 0; j < 16; j++) {
        tmp_iv[j] = iv[j];
    }
    for (int i = 0; i < ciphertext.size() / 16; i++) {

        myAES a1;

        //Übergabe - Array
        uchar tmp[16];
        for (int k = 0; k < 16; k++) {
            tmp[k] = ciphertext[k + 16 * i];
        }

        // Ciphertext
        a1.setCiphertext(tmp);

        // Schluessel
        a1.setSchluessel(key);

        // decrypt
        a1.decrypt(false);

        // Resultat mit IV addieren / XOR
        for (int f = 0; f < 16; f++) {
            a1.getKlartext()[f] = a1.getKlartext()[f]^tmp_iv[f];
        }

        // Neuen IV festlegen und Klartext eintragen
        for (int l = 0; l < 16; l++) {
            tmp_iv[l] = a1.getCiphertext()[l];
            klartext.push_back(a1.getKlartext()[l]);
        }
    }
}

void myCBC::crypt(bool print) {
    ciphertext.clear();
    uchar tmp_iv[16];
    for (int i = 0; i < 16; i++) {
        tmp_iv[i] = iv[i];
    }

    for (int i = 0; i < klartext.size() / 16; i++) {

        myAES a1;
        a1.setSchluessel(key);

        //XOR in Übergabe - Array
        uchar tmp[16];
        for (int j = 0; j < 16; j++) {
            tmp[j] = klartext[j + 16 * i]^tmp_iv[j];
        }

        // Klartext
        a1.setKlartext(tmp);

        // crypt
        a1.crypt(false);


        for (int j = 0; j < 16; j++) {
            tmp_iv[j] = a1.getCiphertext()[j];
            ciphertext.push_back(a1.getCiphertext()[j]);
        }
    }
}

void myCBC::setKlartext(vector<uchar> kt) {
    // Padding mit 0
    if (kt.size() > klartext.size()) {
        int diff = kt.size() - klartext.size();
        for (int i = 0; i < diff; i++) {
            klartext.push_back(0x00);
        }
    }

    // Werte übertragen
    for (int i = 0; i < kt.size(); i++) {
        klartext.at(i) = kt.at(i);
    }
}

void myCBC::setIV(uchar tmp[16]) {
    for (int i = 0; i < 16; i++) {
        iv[i] = tmp[i];
    }
}

void myCBC::setKey(uchar tmp[16]) {
    for (int i = 0; i < 16; i++) {
        key[i] = tmp[i];
    }
}

myCBC::~myCBC() {
}

myECB.h


#ifndef MYECB_H
#define	MYECB_H

#include "myAES.h"
#include <vector>
class myECB {
public:
    // Konstruktoren / Destruktoren
    myECB();
    virtual ~myECB();
    
    //CBC
    void crypt(bool);
    void decrypt(bool);
    
    // Set/Get-Methoden
    void setKey(uchar[16]);
    void setKlartext(vector<uchar>);
    void setCiphertext(vector<uchar>);
    vector<uchar> getKlartext();
    vector<uchar> getCiphertext();
    uchar* getSchluessel();
    
    // Manuelle Eingabe
    void enterKey();    
    void enterKlartext();

private:
    uchar key[16];
    vector<uchar> klartext;
    vector<uchar> ciphertext;

};

#endif	/* MYECB_H */

myECB.cpp


#include "myECB.h"
#include <iomanip>
#include <iostream>

void myECB::enterKey() {
    string tmp = "";
    int diff = 0;
    cout << "Schluessel (16 Zeichen):";
    if (cin >> tmp) {

        if (tmp.length() > 16) {
            cerr << "\nWerte fuer den Schluessel zu groß. Trenne nach 16 Zeichen ab.\n(";
            for (int i = 0; i < tmp.length(); i++) {
                if (i == 16) {
                    cerr << " | ";
                }
                cerr << tmp.at(i);
            }
            cout << ")" << endl;
        }

        if (tmp.length() < 16) {
            cerr << "\nWert fuer den Klartext zu klein. Fuelle mit Nullen auf.\n";
            diff = 16 - tmp.length();
            for (int i = 0; i < diff; i++) {
                tmp.push_back('\0');
            }
            cout << endl;
        }

        for (int i = 0; i < 16; i++) {
            key[i] = tmp[i];
        }
        cout << endl;
    }
}

vector<uchar> myECB::getKlartext() {
    return klartext;
}

void myECB::enterKlartext() {
    klartext.clear();
    string tmp = "";
    cout << "Klartext (Beliebig viele Zeichen):";
    if (cin >> tmp) {
        for (int i = 0; i < tmp.size(); i++) {
            klartext.push_back(tmp[i]);
        }
        cout << endl;
    }

    if (tmp.size() % 16 != 0) {
        cerr << "\nLetzter Klartext-Block nicht vollstaendig. Fuelle mit Nullen auf.\n";
        for (int i = 0; i < 16 - tmp.size() % 16; i++) {
            klartext.push_back('\0');
        }
        cout << endl;
    }
}

myECB::myECB() {

    // Default Parameter
    uchar newKey[16] = {0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c};
    uchar newKlartext[16] = {0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a};

    // Schluessel setzen
    for (int i = 0; i < 16; i++) {
        key[i] = newKey[i];
    }

    // Klartext setzen
    for (int i = 0; i < 16; i++) {
        klartext.push_back(newKlartext[i]);
    }
}

vector<uchar> myECB::getCiphertext() {
    return ciphertext;
}

void myECB::decrypt(bool print) {
    klartext.clear();

    for (int i = 0; i < ciphertext.size() / 16; i++) {

        myAES a1;

        //Übergabe - Array
        uchar tmp[16];
        for (int j = 0; j < 16; j++) {
            tmp[j] = ciphertext[j + 16 * i];
        }

        // Ciphertext
        a1.setCiphertext(tmp);

        // Schluessel
        a1.setSchluessel(key);

        // crypt
        a1.decrypt(false);

        // Resultat mit IV addieren
        for (int j = 0; j < 16; j++) {
            klartext.push_back(a1.getKlartext()[j]);
        }
    }
}

void myECB::crypt(bool print) {
    ciphertext.clear();

    for (int i = 0; i < klartext.size() / 16; i++) {

        myAES a1;
        a1.setSchluessel(key);

        //XOR in Übergabe - Array
        uchar tmp[16];
        for (int j = 0; j < 16; j++) {
            tmp[j] = klartext[j + 16 * i]; //^tmp_iv[j];
        }

        // Klartext
        a1.setKlartext(tmp);

        // crypt
        a1.crypt(false);


        for (int j = 0; j < 16; j++) {
            ciphertext.push_back(a1.getCiphertext()[j]);
        }
    }
}

void myECB::setKlartext(vector<uchar> kt) {
    if (kt.size() > klartext.size()) {
        int diff = kt.size() - klartext.size();
        for (int i = 0; i < diff; i++) {
            klartext.push_back(0x00);
        }
    }
    for (int i = 0; i < kt.size(); i++) {
        klartext.at(i) = kt.at(i);
    }
}

void myECB::setKey(uchar tmp[16]) {
    for (int i = 0; i < 16; i++) {
        key[i] = tmp[i];
    }
}

myECB::~myECB() {
}

myGUI.h


#ifndef MYGUI_H
#define	MYGUI_H

#include <iostream>
#include "myCBC.h"
#include "myECB.h"

class myGUI {
public:
    // Menu
    myGUI();
    void menuAES();
    void menuCBC();
    void menuECB();
    // Tests
    bool checkAES();
    bool checkCBC();
    bool checkECB();
    virtual ~myGUI();
private:
};

#endif	/* MYGUI_H */

myGUI.cpp


//Präprozessor-Direktiven
#include "support.h"
#include "myGUI.h"
#include <vector>
#include <iostream>
#include  <iomanip>


//Namensbereich Auflösung
using namespace std;

// <editor-fold defaultstate="collapsed" desc="Methoden bzgl. AES">

bool myGUI::checkAES() {

    bool returnValue = false;

    // Testvektoren
    uchar schluessel[16] = {0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c};
    uchar klartext_1[16] = {0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a};
    uchar klartext_2[16] = {0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c, 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51};
    uchar klartext_3[16] = {0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11, 0xe5, 0xfb, 0xc1, 0x19, 0x1a, 0x0a, 0x52, 0xef};
    uchar cipher_1[16] = {0x3a, 0xd7, 0x7b, 0xb4, 0x0d, 0x7a, 0x36, 0x60, 0xa8, 0x9e, 0xca, 0xf3, 0x24, 0x66, 0xef, 0x97};
    uchar cipher_2[16] = {0xf5, 0xd3, 0xd5, 0x85, 0x03, 0xb9, 0x69, 0x9d, 0xe7, 0x85, 0x89, 0x5a, 0x96, 0xfd, 0xba, 0xaf};
    uchar cipher_3[16] = {0x43, 0xb1, 0xcd, 0x7f, 0x59, 0x8e, 0xce, 0x23, 0x88, 0x1b, 0x00, 0xe3, 0xed, 0x03, 0x06, 0x88};

    // Test#1
    myAES aes1;
    aes1.setKlartext(klartext_1);
    aes1.setSchluessel(schluessel);
    aes1.crypt(false);

    // Test#2
    myAES aes2;
    aes2.setKlartext(klartext_2);
    aes2.setSchluessel(schluessel);
    aes2.crypt(false);

    // Test#3
    myAES aes3;
    aes3.setKlartext(klartext_3);
    aes3.setSchluessel(schluessel);
    aes3.crypt(false);

    // Prüfung
    bool isWorking = areEqual(aes3.getCiphertext(), cipher_3) && areEqual(aes2.getCiphertext(), cipher_2) && areEqual(aes1.getCiphertext(), cipher_1);
    if (isWorking) {
        returnValue = true;
    } else {

        returnValue = false;
    }
    return returnValue;
}

void myGUI::menuAES() {

    // Variablen initialisieren
    bool run = true;
    unsigned int lowest = 1;
    unsigned int end = 4;
    int input = end;

    // aes initialisieren und verschlüsseln
    myAES aes;
    aes.crypt(false);

    //Menu Eingabe
    while (run) {
        cout << "\nBitte waehlen sie aus:\n";
        cout << "(1) Text verschluesseln \n";
        cout << "(2) Text und Schluessel eingeben \n";
        cout << "(3) Text entschluesseln \n";
        cout << "(4) Zurueck\n";
        cout << "> ";

        // Eingabe überprüfen
        input = validatedInput(lowest, end);

        // Auswahl
        if (input == 1) {
            aes.crypt(true);
            printMatrix(aes.getKlartext(), "Klartext");
            printMatrix(aes.getSchluessel(), "Schluessel");
            printMatrix(aes.getCiphertext(), "Cipher");
        }
        if (input == 2) {
            aes.enterKlartext();
            aes.enterSchluessel();
            aes.crypt(true);
            printMatrix(aes.getKlartext(), "Klartext");
            printMatrix(aes.getSchluessel(), "Schluessel");
            printMatrix(aes.getCiphertext(), "Cipher");
        }
        if (input == 3) {
            aes.decrypt(true);
            printMatrix(aes.getCiphertext(), "Cipher");
            printMatrix(aes.getSchluessel(), "Schluessel");
            printMatrix(aes.getKlartext(), "Klartext");
        }
        if (input == end) {
            run = false;
        }
        if (input == -1) {

            cerr << "Ungueltige Eingabe getätigt.\nBitte nochmal eingeben.\n";
            cout << endl;
        }
    }
}

// </editor-fold>

// <editor-fold defaultstate="collapsed" desc="Methoden bzgl. CBC">

bool myGUI::checkCBC() {
    bool returnValue = false;

    // Test #1  - 16 Byte Testvektoren
    uchar keyB[16] = {0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c};
    uchar ivB[16] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F};
    uchar klartextB1[16] = {0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a};
    uchar ciphertextB1[16] = {0x76, 0x49, 0xab, 0xac, 0x81, 0x19, 0xb2, 0x46, 0xce, 0xe9, 0x8e, 0x9b, 0x12, 0xe9, 0x19, 0x7d};

    // Container 
    vector<uchar> cipherB1;
    vector<uchar> ktB;

    // Container füllen
    for (int i = 0; i < 16; i++) {
        ktB.push_back(klartextB1[i]);
        cipherB1.push_back(ciphertextB1[i]);
    }

    // cbc intialisieren
    myCBC cbcB;
    cbcB.setKey(keyB);
    cbcB.setIV(ivB);
    cbcB.setKlartext(ktB);

    // Verschlüsseln
    cbcB.crypt(false);

    // Test#2 - 32 Byte Testvektoren
    uchar klartextA1[16] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f};
    uchar klartextA2[16] = {0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f};
    uchar ivA[16] = {0x56, 0x2e, 0x17, 0x99, 0x6d, 0x09, 0x3d, 0x28, 0xdd, 0xb3, 0xba, 0x69, 0x5a, 0x2e, 0x6f, 0x58};
    uchar keyA[16] = {0xc2, 0x86, 0x69, 0x6d, 0x88, 0x7c, 0x9a, 0xa0, 0x61, 0x1b, 0xbb, 0x3e, 0x20, 0x25, 0xa4, 0x5a};
    uchar ciphertextA1[16] = {0xd2, 0x96, 0xcd, 0x94, 0xc2, 0xcc, 0xcf, 0x8a, 0x3a, 0x86, 0x30, 0x28, 0xb5, 0xe1, 0xdc, 0x0a};
    uchar ciphertextA2[16] = {0x75, 0x86, 0x60, 0x2d, 0x25, 0x3c, 0xff, 0xf9, 0x1b, 0x82, 0x66, 0xbe, 0xa6, 0xd6, 0x1a, 0xb1};

    // Container
    vector<uchar> cipherA1;
    vector<uchar> test;

    // Container füllen
    for (int i = 0; i < 16; i++) {
        test.push_back(klartextA1[i]);
        cipherA1.push_back(ciphertextA1[i]);
    }

    for (int i = 0; i < 16; i++) {
        test.push_back(klartextA2[i]);
        cipherA1.push_back(ciphertextA2[i]);
    }

    // cbc initialisieren
    myCBC cbcA;
    cbcA.setKey(keyA);
    cbcA.setIV(ivA);
    cbcA.setKlartext(test);

    // Verschlüsseln
    cbcA.crypt(false);

    //Prüfung auf Korrektheit
    bool isWorking = areEqual(cbcA.getCiphertext(), cipherA1) && areEqual(cbcB.getCiphertext(), cipherB1);

    if (isWorking) {
        returnValue = true;
    } else {
        returnValue = false;
    }
    return returnValue;
}

void myGUI::menuCBC() {

    // cbc mit Standard Werten initialisieren
    myCBC cbc;
    cbc.crypt(false);

    // Variablen initialisieren
    bool run = true;
    unsigned int lowest = 1;
    unsigned int end = 5;
    int input = end;

    //Menu Eingabe
    while (run) {
        cout << "\nBitte waehlen sie aus:\n";
        cout << "(1) Text verschluesseln \n";
        cout << "(2) Text und Schluessel eingeben \n";
        cout << "(3) Bild ver- und entschluesseln\n";
        cout << "(4) Text entschluesseln\n";
        cout << "(5) Zurueck\n";
        cout << "> ";

        // Überprüfe Eingabe
        input = validatedInput(lowest, end);

        // Auswahl
        if (input == 1) {
            cbc.crypt(true);
            printMatrix(cbc.getKlartext(), "Klartext");
            printMatrix(cbc.getSchluessel(), "Schluessel");
            printMatrix(cbc.getCiphertext(), "Cipher");
        }
        if (input == 2) {
            cbc.enterIV();
            cbc.enterKey();
            cbc.enterKlartext();
            cbc.crypt(true);
            printMatrix(cbc.getKlartext(), "Klartext");
            printMatrix(cbc.getSchluessel(), "Schluessel");
            printMatrix(cbc.getCiphertext(), "Cipher");
        }
        if (input == 3) {
            //Fülle Vektor mit Punkten
            vector<uchar> myImg;
            fillImage(myImg);

            // Gebe Klartext aus
            printImage(myImg);

            // Setze Klartext, verschlüssle und gebe Cipher aus
            cbc.setKlartext(myImg);
            cbc.crypt(false);
            printImage(cbc.getCiphertext());

            // Entschlüssle und gebe Klartext aus
            cbc.decrypt(false);
            printImage(cbc.getKlartext());
        }
        if (input == 4) {
            cbc.decrypt(true);
            printMatrix(cbc.getCiphertext(), "Cipher");
            printMatrix(cbc.getSchluessel(), "Schluessel");
            printMatrix(cbc.getKlartext(), "Klartext");
        }
        if (input == end) {
            run = false;
        }
        if (input == -1) {
            cerr << "Ungueltige Eingabe getätigt.\nBitte nochmal eingeben.\n";
            cout << endl;
        }
    }

}

// </editor-fold>

// <editor-fold defaultstate="collapsed" desc="Methoden bzgl. ECB">

bool myGUI::checkECB() {
    bool returnValue = false;

    //16 Byte Testvektoren
    uchar schluessel[16] = {0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c};

    uchar klartext_1[16] = {0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a};
    uchar klartext_2[16] = {0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c, 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51};
    uchar klartext_3[16] = {0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11, 0xe5, 0xfb, 0xc1, 0x19, 0x1a, 0x0a, 0x52, 0xef};

    uchar cipher_1[16] = {0x3a, 0xd7, 0x7b, 0xb4, 0x0d, 0x7a, 0x36, 0x60, 0xa8, 0x9e, 0xca, 0xf3, 0x24, 0x66, 0xef, 0x97};
    uchar cipher_2[16] = {0xf5, 0xd3, 0xd5, 0x85, 0x03, 0xb9, 0x69, 0x9d, 0xe7, 0x85, 0x89, 0x5a, 0x96, 0xfd, 0xba, 0xaf};
    uchar cipher_3[16] = {0x43, 0xb1, 0xcd, 0x7f, 0x59, 0x8e, 0xce, 0x23, 0x88, 0x1b, 0x00, 0xe3, 0xed, 0x03, 0x06, 0x88};

    // Container
    vector<uchar> cipherB1;
    vector<uchar> ktB;

    // Fülle Container mit Block 1
    for (int i = 0; i < 16; i++) {
        ktB.push_back(klartext_1[i]);
        cipherB1.push_back(cipher_1[i]);
    }

    // Fülle Container mit Block 2
    for (int i = 0; i < 16; i++) {
        ktB.push_back(klartext_2[i]);
        cipherB1.push_back(cipher_2[i]);
    }

    // Fülle Container mit Block 3
    for (int i = 0; i < 16; i++) {
        ktB.push_back(klartext_3[i]);
        cipherB1.push_back(cipher_3[i]);
    }

    // Verschlüssele mit Hilfe des Schlüssels und den 3 Blöcken
    myECB ecb;
    ecb.setKey(schluessel);
    ecb.setKlartext(ktB);
    ecb.crypt(false);

    //Prüfung auf Gleichheit
    bool isWorking = areEqual(ecb.getCiphertext(), cipherB1);
    if (isWorking) {
        returnValue = true;
    } else {
        returnValue = false;
    }
    return returnValue;
}

void myGUI::menuECB() {


    //Initialisiere ecb mit Standard-Werten
    myECB ecb;
    ecb.crypt(false);

    //Initialisiere Eingabe-Variablen 
    bool run = true;
    unsigned int lowest = 1;
    unsigned int end = 5;
    int input = end;

    //Menu Eingabe
    while (run) {

        cout << "\nBitte waehlen sie aus:\n";
        cout << "(1) Text verschluesseln \n";
        cout << "(2) Text und Schluessel eingeben \n";
        cout << "(3) Bild ver- und entschluesseln\n";
        cout << "(4) Text entschluesseln\n";
        cout << "(5) Zurueck\n";
        cout << "> ";

        // Prüfe Eingabe
        input = validatedInput(lowest, end);

        // Auswahl
        if (input == 1) {
            ecb.crypt(true);
        }
        if (input == 2) {
            ecb.enterKey();
            ecb.enterKlartext();
            ecb.crypt(true);
        }
        if (input == 3) {
            // Erstelle Vektor mit Bildpunkten
            vector<uchar> myImg;
            fillImage(myImg);

            // Gebe Klartext aus
            printImage(myImg);
            ecb.setKlartext(myImg);

            // Verschlpsseln und Gebe Cipher aus
            ecb.crypt(false);
            printImage(ecb.getCiphertext());

            // Entschlüsseln und Klartext ausgeben
            ecb.decrypt(false);
            printImage(ecb.getKlartext());
        }
        if (input == 4) {
            ecb.decrypt(true);
        }
        if (input == end) {
            run = false;
        }
        if (input == -1) {
            cerr << "Ungueltige Eingabe getätigt.\nBitte nochmal eingeben.\n";
            cout << endl;
        }
    }

}

// </editor-fold>

// <editor-fold defaultstate="collapsed" desc="Konstrukturen und Destruktoren">

myGUI::myGUI() {
    //Menu-Variablen

    unsigned int lowest = 1;
    unsigned int end = 4;
    int input = end;
    bool run = true;

    //Start
    cout << "#### Kryptographie Sommersemester 2013 ####\n";
    cout << "Nils Rogmann (725915) und Maximilian Krieg (725922)\n";

    // Begrüßung und Information
    cout << "\nHerzlich willkommen.\n";
    cout << "Das Programm wird nun mit Hilfe von Testvektoren geprueft.\n";

    // AES Check
    cout << "\nAES:\t\t";
    if (checkAES()) {
        cout << "OK";
    } else {
        cerr << "Fehler";
    }

    // CBC Check
    cout << "\nAES mit CBC:\t";
    if (checkCBC()) {
        cout << "OK";
    } else {
        cerr << "Fehler";
    }


    // ECB Check
    cout << "\nAES mit ECB:\t";
    if (checkECB()) {
        cout << "OK";
    } else {
        cerr << "Fehler";
    }

    cout << endl;

    //Menu Eingabe
    while (run) {
        cout << "\nBitte waehlen sie aus:\n";
        cout << "(1) AES\n";
        cout << "(2) AES mit CBC\n";
        cout << "(3) AES mit ECB\n";
        cout << "(4) Programm beenden\n";
        cout << "> ";

        // Prüfe Eingabe auf Gültigkeit
        input = validatedInput(lowest, end);

        // Aufrufe
        if (input == 1) {
            cout << "#### AES ####\n";
            menuAES();
            cout << endl;
        }

        if (input == 2) {
            cout << "#### AES mit CBC ####\n";
            menuCBC();
            cout << endl;
        }


        if (input == 3) {
            cout << "#### AES mit ECB ####\n";
            menuECB();
            cout << endl;
        }

        // Fehler
        if (input == -1) {
            cerr << "Ungueltige Eingabe getätigt.\nBitte nochmal eingeben.\n";
            cout << endl;
        }

        // Beenden
        if (input == end) {

            cout << "Programm wird beendet.\n";
            run = false;
            cout << endl;
        }
    }
}//myGUI

myGUI::~myGUI() {
}//~myGUI

// </editor-fold>

support.h


#include <iostream>
#include <iomanip>
#include <vector>
using namespace std;
typedef unsigned char uchar;

void printMatrix(vector<uchar> v, string name) {
    cout << name << ": \n";

    int add =0;
    for (int j = 0; j < v.size()/16; j++) {
        for (int i = 0; i < 4; i++) {
            cout << hex << setfill('0') << setw(2) << nouppercase << (int) v[i+add] << " ";
            cout << hex << setfill('0') << setw(2) << nouppercase << (int) v[i + 4+add] << " ";
            cout << hex << setfill('0') << setw(2) << nouppercase << (int) v[i + 8+add] << " ";
            cout << hex << setfill('0') << setw(2) << nouppercase << (int) v[i + 12+add] << " ";
            cout << endl;
        }
        add=add+16;
        cout << endl;
    }
    cout << endl;
}

void printMatrix(uchar v[16], string name) {
    cout << name << ": \n";
    for (int i = 0; i < 4; i++) {
        cout << hex << setfill('0') << setw(2) << nouppercase << (int) v[i] << " ";
        cout << hex << setfill('0') << setw(2) << nouppercase << (int) v[i + 4] << " ";
        cout << hex << setfill('0') << setw(2) << nouppercase << (int) v[i + 8] << " ";
        cout << hex << setfill('0') << setw(2) << nouppercase << (int) v[i + 12] << " ";
        cout << endl;
    }
    cout << endl;

    /*
    for (int i=0;i<16;i++)
        cout << hex<<(int) v[i];
     * */
}

int validatedInput(unsigned int lowest, unsigned int highest) {
    int tmp = 0;
    cin.clear();
    if (cin >> tmp) {//Eingabe ist in Ordnung
        cout << endl;
        if (tmp >= lowest && tmp <= highest) {//Eingabe liegt in den Parametern

            return tmp;
        }
    } else {
        // Falsche Inhalte verwerfen und Status zurücksetzen
        string trash = "";
        cin.clear();
        std::getline(std::cin, trash);
    }
    return -1;
}

// 16x16 Matrix ausgeben

void printImage(vector<uchar> myImg) {
    int add = 0;
    for (int j = 0; j < 4; j++) {
        for (int i = 0; i < 4; i++) {
            for (int k = 0; k <= 60; k) {
                cout << hex << setfill('0') << setw(2) << nouppercase << (int) myImg.at(i + k + add) << " ";
                k = k + 4;
            }
            cout << endl;
        }

        add = add + 64;
    }
    cout << endl << endl;
}

// 16x16 Matrix füllen

void fillImage(vector<uchar>& v) {
    // Alles auf 0 setzen
    // Außer den Inneren bereich, diesen auf 1
    for (int y = 0; y < 16; y++) {
        for (int x = 0; x < 16; x++) {
            if (y == 5 || y == 6 || y == 9 || y == 10)
                v.push_back(0x1);
            else {
                v.push_back(0x0);
            }
        }
    }

    //Manuell Randpunkte des Kreises setzen
    v[19] = 0x1;
    v[22] = 0x1;
    v[23] = 0x1;
    v[26] = 0x1;
    v[27] = 0x1;
    v[30] = 0x1;
    v[31] = 0x1;
    v[34] = 0x1;
    v[35] = 0x1;
    v[38] = 0x1;
    v[39] = 0x1;
    v[42] = 0x1;
    v[43] = 0x1;
    v[47] = 0x1;
    v[73] = 0x1;
    v[74] = 0x1;
    v[75] = 0x1;
    v[76] = 0x1;
    v[77] = 0x1;
    v[78] = 0x1;
    v[79] = 0x1;
    v[112] = 0x1;
    v[113] = 0x1;
    v[114] = 0x1;
    v[115] = 0x1;
    v[117] = 0x1;
    v[118] = 0x1;
    v[119] = 0x1;
    v[136] = 0x1;
    v[137] = 0x1;
    v[138] = 0x1;
    v[140] = 0x1;
    v[141] = 0x1;
    v[142] = 0x1;
    v[143] = 0x1;
    v[176] = 0x1;
    v[177] = 0x1;
    v[178] = 0x1;
    v[179] = 0x1;
    v[180] = 0x1;
    v[181] = 0x1;
    v[182] = 0x1;
    v[208] = 0x1;
    v[212] = 0x1;
    v[213] = 0x1;
    v[216] = 0x1;
    v[217] = 0x1;
    v[220] = 0x1;
    v[221] = 0x1;
    v[224] = 0x1;
    v[225] = 0x1;
    v[228] = 0x1;
    v[229] = 0x1;
    v[232] = 0x1;
    v[233] = 0x1;
    v[236] = 0x1;
}

// Gleichheitsprüfung

template<class T>
bool areEqual(T arr1, T arr2) {
    bool tmp = false;
    for (int i = 0; i < 16; i++) {
        if (arr1[i] == arr2[i]) {
            tmp = true;
        } else {
            cout << hex << arr1[i] << "!=" << arr2[i] << endl;
            tmp = false;
            break;
        }
    }
    return tmp;
}

Schreiben Sie einen Kommentar

Ihre E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert

Diese Website verwendet Akismet, um Spam zu reduzieren. Erfahren Sie, wie Ihre Kommentardaten verarbeitet werden.

'); } cout << endl; } for (int i = 0; i < 16; i++) { arr[i] = tmp[i]; } cout << endl; } } void myAES::enterKlartext() { enterValues(klartext, "Klartext"); } void myAES::enterSchluessel() { enterValues(schluessel, "Schluessel"); } //</editor-fold> //<editor-fold defaultstate="collapsed" desc="Set/Get-Methoden"> void myAES::setCiphertext(uchar tmp[16]) { for (int i = 0; i < 16; i++) { ciphertext[i] = tmp[i]; } } void myAES::setKlartext(uchar tmp[16]) { for (int i = 0; i < 16; i++) { klartext[i] = tmp[i]; } } void myAES::setSchluessel(uchar tmp[16]) { for (int i = 0; i < 16; i++) { schluessel[i] = tmp[i]; } } uchar* myAES::getSchluessel() { return schluessel; } uchar* myAES::getCiphertext() { return ciphertext; } uchar* myAES::getKlartext() { return klartext; } //</editor-fold>

myCBC.h


#ifndef MYCBC_H
#define	MYCBC_H
#include "myAES.h"
#include <vector>
class myCBC {
public:
    // Konstruktoren / Destruktoren
    myCBC();
    virtual ~myCBC();
    
    //CBC
    void crypt(bool);
    void decrypt(bool);
    
    // Set/Get-Methoden
    void setKey(uchar[16]);
    void setIV(uchar[16]);
    void setKlartext(vector<uchar>);
    void setCiphertext(vector<uchar>);
    vector<uchar> getKlartext();
    vector<uchar> getCiphertext();
    uchar* getSchluessel();
    uchar* getIV();
    
    // Manuelle Eingabe
    void enterKey();
    void enterIV();
    void enterKlartext();
    
private:
    uchar iv[16];
    uchar key[16];
    vector<uchar> klartext;
    vector<uchar> ciphertext;
};

myCBC.cpp


#include "myCBC.h"
#include <math.h>
#include <iostream>
#include <iomanip>
using namespace std;
uchar* myCBC::getSchluessel() {
return key;
}
vector<uchar> myCBC::getKlartext() {
return klartext;
}
void enterValue(uchar arr[], string name) {
string tmp = "";
int diff = 0;
cout << name << ": (16 Zeichen):";
if (cin >> tmp) {
if (tmp.length() > 16) {
cerr << "\nWerte fuer den" << name << " zu groß. Trenne nach 16 Zeichen ab.\n(";
for (int i = 0; i < tmp.length(); i++) {
if (i == 16) {
cerr << " | ";
}
cerr << tmp.at(i);
}
cout << ")" << endl;
}
if (tmp.length() < 16) {
cerr << "\nWert fuer den Klartext zu klein. Fuelle mit Nullen auf.\n";
diff = 16 - tmp.length();
for (int i = 0; i < diff; i++) {
tmp.push_back('
Menu Close

Kryptologie (Praktikum 4)

Skript-AnfangKryptouebung3 – Seite 1
Skript-EndeKryptouebung3 – Seite 1

main.cpp


#include <cstdlib>
#include <iostream>
#include <iomanip>
#include "myGUI.h"


// Using-Deklarationen
using namespace std;

int main(int argc, char** argv) {
    //Start GUI
    myGUI gui;
}// main

myAES.h


#ifndef MYAES_H
#define	MYAES_H

#include <iostream>

using namespace std;
// Typedefs
typedef unsigned char uchar;

class myAES {
public:
    // Konstruktoren/Destruktoren
    myAES();
    virtual ~myAES();

    // Manuelle Eingabe
    void enterKlartext();
    void enterSchluessel();

    // Set/Get-Methoden
    void setKlartext(uchar[16]);
    void setSchluessel(uchar[16]);
    void setCiphertext(uchar[16]);
    uchar* getKlartext();
    uchar* getSchluessel();
    uchar* getCiphertext();

    // Crypt
    void crypt(bool);
    void mixcolumns();
    void shiftrows();
    void schluesselexpansion(uchar[][44], int, int, int);
    void rotword(uchar[], int);
    uchar mix(uchar, unsigned int);
    void subbytes(uchar [], uchar [], int);
    
    // Decrypt
    void decrypt(bool);
    uchar gmul(uchar, uchar);
    void invert_mixcolumns();
    void invert_shiftrows();    
    
private:
    uchar klartext[16];
    uchar schluessel[16];
    uchar ciphertext[16];
};



#endif	/* MYAES_H */

myAES.cpp


#include "myAES.h"

using namespace std;

//<editor-fold defaultstate="collapsed" desc="Boxen">

unsigned char Sbox[256] = {//  s-box
    0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
    0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
    0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
    0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
    0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,
    0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
    0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,
    0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,
    0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
    0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
    0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,
    0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
    0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
    0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
    0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
    0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16
};

unsigned char sbox_inverse[256] = {
    0x52, 0x09, 0x6A, 0xD5, 0x30, 0x36, 0xA5, 0x38, 0xBF, 0x40, 0xA3, 0x9E, 0x81, 0xF3, 0xD7, 0xFB,
    0x7C, 0xE3, 0x39, 0x82, 0x9B, 0x2F, 0xFF, 0x87, 0x34, 0x8E, 0x43, 0x44, 0xC4, 0xDE, 0xE9, 0xCB,
    0x54, 0x7B, 0x94, 0x32, 0xA6, 0xC2, 0x23, 0x3D, 0xEE, 0x4C, 0x95, 0x0B, 0x42, 0xFA, 0xC3, 0x4E,
    0x08, 0x2E, 0xA1, 0x66, 0x28, 0xD9, 0x24, 0xB2, 0x76, 0x5B, 0xA2, 0x49, 0x6D, 0x8B, 0xD1, 0x25,
    0x72, 0xF8, 0xF6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xD4, 0xA4, 0x5C, 0xCC, 0x5D, 0x65, 0xB6, 0x92,
    0x6C, 0x70, 0x48, 0x50, 0xFD, 0xED, 0xB9, 0xDA, 0x5E, 0x15, 0x46, 0x57, 0xA7, 0x8D, 0x9D, 0x84,
    0x90, 0xD8, 0xAB, 0x00, 0x8C, 0xBC, 0xD3, 0x0A, 0xF7, 0xE4, 0x58, 0x05, 0xB8, 0xB3, 0x45, 0x06,
    0xD0, 0x2C, 0x1E, 0x8F, 0xCA, 0x3F, 0x0F, 0x02, 0xC1, 0xAF, 0xBD, 0x03, 0x01, 0x13, 0x8A, 0x6B,
    0x3A, 0x91, 0x11, 0x41, 0x4F, 0x67, 0xDC, 0xEA, 0x97, 0xF2, 0xCF, 0xCE, 0xF0, 0xB4, 0xE6, 0x73,
    0x96, 0xAC, 0x74, 0x22, 0xE7, 0xAD, 0x35, 0x85, 0xE2, 0xF9, 0x37, 0xE8, 0x1C, 0x75, 0xDF, 0x6E,
    0x47, 0xF1, 0x1A, 0x71, 0x1D, 0x29, 0xC5, 0x89, 0x6F, 0xB7, 0x62, 0x0E, 0xAA, 0x18, 0xBE, 0x1B,
    0xFC, 0x56, 0x3E, 0x4B, 0xC6, 0xD2, 0x79, 0x20, 0x9A, 0xDB, 0xC0, 0xFE, 0x78, 0xCD, 0x5A, 0xF4,
    0x1F, 0xDD, 0xA8, 0x33, 0x88, 0x07, 0xC7, 0x31, 0xB1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xEC, 0x5F,
    0x60, 0x51, 0x7F, 0xA9, 0x19, 0xB5, 0x4A, 0x0D, 0x2D, 0xE5, 0x7A, 0x9F, 0x93, 0xC9, 0x9C, 0xEF,
    0xA0, 0xE0, 0x3B, 0x4D, 0xAE, 0x2A, 0xF5, 0xB0, 0xC8, 0xEB, 0xBB, 0x3C, 0x83, 0x53, 0x99, 0x61,
    0x17, 0x2B, 0x04, 0x7E, 0xBA, 0x77, 0xD6, 0x26, 0xE1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0C, 0x7D
};

unsigned char Rcon[256] = {
    0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a,
    0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39,
    0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a,
    0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8,
    0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef,
    0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc,
    0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b,
    0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3,
    0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94,
    0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20,
    0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35,
    0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f,
    0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04,
    0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63,
    0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd,
    0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d
};
//</editor-fold>

//<editor-fold defaultstate="collapsed" desc="AES-Methoden">

void myAES::subbytes(uchar sbox[], uchar tmp[], int arrSize) {
    for (int i = 0; i < arrSize; i++) {
        tmp[i] = sbox[tmp[i]];
    }
}// subbytes

uchar myAES::mix(uchar byte, unsigned int mixvalue) {
    unsigned char retValue;
    switch (mixvalue) {
        case 1:
            retValue = byte;
            break;
        case 2:
            retValue = byte << 1;
            if (byte & 0x80) {
                retValue = retValue ^ 0x1b;
            }
            break;
        case 3:
            retValue = byte << 1;
            if (byte & 0x80) {
                retValue = retValue ^ 0x1b;
            }
            retValue = retValue^byte;
            break;
    }
    return retValue;
}

void addRoundKey(uchar array[], uchar matrix[][44], int iReihe, int iSpalte, int iRunde) {
    int pos = 0;
    for (int i = iRunde * 4; i < ((iRunde * 4) + 4) && i < iSpalte; i++) {
        for (int k = 0; k < iReihe; k++) {
            array[pos] = array[pos] ^ matrix[k][i];
            pos++;
        }
    }
}// addroundkey

void myAES::rotword(uchar column[], int iReihe) {
    uchar tmp = column[0];
    for (int i = 1; i < iReihe; i++) {
        column[i - 1] = column[i];
    }
    column[iReihe - 1] = tmp;
} // rotword

void myAES::schluesselexpansion(uchar matrix[][44], int iReihe, int iSpalte, int iLaenge) {
    // Alle Spalten durchlaufen
    int pos = 0;

    for (int i = 0; i < iSpalte; i++) {
        if (i < 4) { // Schluessel in erste vier Spalten kopieren
            for (int k = 0; k < iReihe && pos < iLaenge; k++) {
                matrix[k][i] = schluessel[pos];
                pos++;
                //cout << hex << "matrix[" << k << "][" << i << "] = " << (int) matrix[k][i] << endl;
            }
        } else { // i > 4
            if (i % 4 == 0) {// erste Spalte eines Schluessels
                // Spalte in Hilfsarray kopieren
                uchar tmp[iReihe]; // i-1
                uchar tmp2[iReihe]; // i-4
                for (int k = 0; k < iReihe; k++) {
                    tmp[k] = matrix[k][i - 1];
                    tmp2[k] = matrix[k][i - 4];
                }

                rotword(tmp, iReihe);

                subbytes(Sbox, tmp, iReihe);

                // Spalte[i-4] XOR subbytes[rotword[i-i]
                for (int k = 0; k < iReihe; k++) {
                    tmp[k] = tmp[k] ^ tmp2[k];
                }

                // tmp[0] XOR (i/4)
                tmp[0] = tmp[0] ^ Rcon[i / iReihe];

                // tmp[k] an Spalte[k][i] kopieren
                for (int k = 0; k < iReihe; k++) {
                    matrix[k][i] = tmp[k];
                }

            } else {
                //cout << "i " << i << endl;
                for (int k = 0; k < iReihe; k++) {
                    matrix[k][i] = matrix[k][i - 4] ^ matrix[k][i - 1];
                }
            }
        }
    }
}// schluesselexpansion

void myAES::shiftrows() {
    uchar copys[16] = {};

    //reihe 1   
    copys[0] = ciphertext[0];
    copys[4] = ciphertext[4];
    copys[8] = ciphertext[8];
    copys[12] = ciphertext[12];

    //reihe 2
    copys[1] = ciphertext[5];
    copys[5] = ciphertext[9];
    copys[9] = ciphertext[13];
    copys[13] = ciphertext[1];

    // reihe 3
    copys[2] = ciphertext[10];
    copys[6] = ciphertext[14];
    copys[10] = ciphertext[2];
    copys[14] = ciphertext[6];

    //reihe 4
    copys[3] = ciphertext[15];
    copys[7] = ciphertext[3];
    copys[11] = ciphertext[7];
    copys[15] = ciphertext[11];

    //umschreiben   
    for (int i = 0; i < 16; i++) {
        ciphertext[i] = copys[i];
    }
}// shiftrows

void myAES::mixcolumns() {
    for (int i = 0; i < 4; i++) {
        uchar sj0 = mix(ciphertext[i * 4], 2)^mix(ciphertext[i * 4 + 1], 3)^mix(ciphertext[i * 4 + 2], 1)^mix(ciphertext[i * 4 + 3], 1);
        uchar sj1 = mix(ciphertext[i * 4], 1)^mix(ciphertext[i * 4 + 1], 2)^mix(ciphertext[i * 4 + 2], 3)^mix(ciphertext[i * 4 + 3], 1);
        uchar sj2 = mix(ciphertext[i * 4], 1)^mix(ciphertext[i * 4 + 1], 1)^mix(ciphertext[i * 4 + 2], 2)^mix(ciphertext[i * 4 + 3], 3);
        uchar sj3 = mix(ciphertext[i * 4], 3)^mix(ciphertext[i * 4 + 1], 1)^mix(ciphertext[i * 4 + 2], 1)^mix(ciphertext[i * 4 + 3], 2);
        ciphertext[i * 4] = sj0;
        ciphertext[i * 4 + 1] = sj1;
        ciphertext[i * 4 + 2] = sj2;
        ciphertext[i * 4 + 3] = sj3;
    }
}// mixcolumns

void myAES::crypt(bool output) {

    // Parameter
    int iRunde = 10;
    int iLaenge = 16;

    // Überschreibe ciphertext um diesen fortan zu verwenden
    for (int i = 0; i < 16; i++) {
        ciphertext[i] = klartext[i];
    }

    // Arraygroesse dynamisch bestimmen
    int arrSize = sizeof (ciphertext) / sizeof (ciphertext[0]);

    // Zwischenspeicherung der Rundenschluessel
    int iReihe = 4;
    int iSpalte = 4 * (iRunde + 1);
    uchar carrRundenschluessel[4][44];

    // Schluessel expandieren
    schluesselexpansion(carrRundenschluessel, iReihe, iSpalte, iLaenge);

    // Vorrunde
    for (int k = 0; k < iLaenge; k++) {
        ciphertext[k] = ciphertext[k] ^ schluessel[k];
    }

    // Durchlaufen der Runden
    for (int i = 1; i < iRunde + 1; i++) {

        // S-Box
        subbytes(Sbox, ciphertext, arrSize);

        // Shift Rows
        shiftrows();

        // Mix Columns
        if (i != (iRunde)) { // kein MixColumns in der letzten Runde
            mixcolumns();
        }

        // Rundenschlüssel addieren
        addRoundKey(ciphertext, carrRundenschluessel, iReihe, iSpalte, i);

    }
}

void myAES::invert_shiftrows() {
    uchar copys[16] = {};

    //reihe 1   
    copys[0] = klartext[0];
    copys[4] = klartext[4];
    copys[8] = klartext[8];
    copys[12] = klartext[12];

    //reihe 2
    copys[1] = klartext[13];
    copys[13] = klartext[9];
    copys[9] = klartext[5];
    copys[5] = klartext[1];

    // reihe 3   
    copys[6] = klartext[14];
    copys[2] = klartext[10];
    copys[14] = klartext[6];
    copys[10] = klartext[2];

    //reihe 4
    copys[11] = klartext[15];
    copys[7] = klartext[11];
    copys[3] = klartext[7];
    copys[15] = klartext[3];

    //umschreiben   
    for (int i = 0; i < 16; i++) {
        klartext[i] = copys[i];
    }
}// invert_shiftrows

void myAES::invert_mixcolumns() {
    for (int i = 0; i < 4; i++) {
        uchar sj0 = gmul(klartext[i * 4], 14)^gmul(klartext[i * 4 + 1], 11)^gmul(klartext[i * 4 + 2], 13)^gmul(klartext[i * 4 + 3], 9);
        uchar sj1 = gmul(klartext[i * 4], 9)^gmul(klartext[i * 4 + 1], 14)^gmul(klartext[i * 4 + 2], 11)^gmul(klartext[i * 4 + 3], 13);
        uchar sj2 = gmul(klartext[i * 4], 13)^gmul(klartext[i * 4 + 1], 9)^gmul(klartext[i * 4 + 2], 14)^gmul(klartext[i * 4 + 3], 11);
        uchar sj3 = gmul(klartext[i * 4], 11)^gmul(klartext[i * 4 + 1], 13)^gmul(klartext[i * 4 + 2], 9)^gmul(klartext[i * 4 + 3], 14);
        klartext[i * 4] = sj0;
        klartext[i * 4 + 1] = sj1;
        klartext[i * 4 + 2] = sj2;
        klartext[i * 4 + 3] = sj3;
    }
}

uchar myAES::gmul(uchar a, uchar b) {
    unsigned char p = 0;
    unsigned char hi;

    for (int i = 0; i < 8; ++i) {
        if ((b & 1) == 1)
            p ^= a;
        hi = (a & 0x80);
        a <<= 1;
        if (hi == 0x80)
            a ^= 0x1b;
        b >>= 1;
    }
    return p;
}

void myAES::decrypt(bool output) {

    // Parameter
    int iRunde = 10;
    int iLaenge = 16;


    // Überschreibe klartext um diesen fortan zu verwenden
    for (int i = 0; i < 16; i++) {
        klartext[i] = ciphertext[i];
    }

    // Arraygroesse dynamisch bestimmen
    int arrSize = sizeof (klartext) / sizeof (klartext[0]);

    // Zwischenspeicherung der Rundenschluessel
    int iReihe = 4;
    int iSpalte = 4 * (iRunde + 1);
    uchar carrRundenschluessel[4][44];

    // Schluessel expandieren
    schluesselexpansion(carrRundenschluessel, iReihe, iSpalte, iLaenge);

    // "neue" Vorrunde
    addRoundKey(klartext, carrRundenschluessel, iReihe, iSpalte, 10);

    // Durchlaufen der Runden
    for (int i = 9; i > 0; i--) {

        // Shift Rows
        invert_shiftrows();

        // S-Box
        subbytes(sbox_inverse, klartext, arrSize);

        // Rundenschlüssel addieren
        addRoundKey(klartext, carrRundenschluessel, iReihe, iSpalte, i);

        // Mix Columns
        if (i != 10) { // kein MixColumns in der letzten Runde
            invert_mixcolumns();
        }
    }

    // Letzte Runde
    invert_shiftrows();
    subbytes(sbox_inverse, klartext, arrSize);

    for (int k = 0; k < iLaenge; k++) {
        klartext[k] = klartext[k] ^ schluessel[k];
    }
}// decrypt

//</editor-fold>

//<editor-fold defaultstate="collapsed" desc="Konstruktur/Destruktor">

myAES::myAES() {
    uchar kt[16] = {0x61, 0x62, 0x62, 0x69, 0x6c, 0x64, 0x75, 0x6e, 0x67, 0x73, 0x6d, 0x61, 0x74, 0x72, 0x69, 0x78};
    uchar s[16] = {0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31};
    //uchar c[16] = {0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31};
    for (int i = 0; i < 16; i++) {
        schluessel[i] = s[i];
        klartext[i] = kt[i];
    }
}

myAES::~myAES() {
}
//</editor-fold>

//<editor-fold defaultstate="collapsed" desc="Manuelle Eingabe">

void enterValues(uchar arr[], string name) {
    string tmp = "";
    int diff = 0;
    cout << name << ": (16 Zeichen):";
    if (cin >> tmp) {

        if (tmp.length() > 16) {
            cerr << "\nWerte fuer den" << name << " zu groß. Trenne nach 16 Zeichen ab.\n(";
            for (int i = 0; i < tmp.length(); i++) {
                if (i == 16) {
                    cerr << " | ";
                }
                cerr << tmp.at(i);
            }
            cout << ")" << endl;
        }

        if (tmp.length() < 16) {
            cerr << "\nWert fuer den Klartext zu klein. Fuelle mit Nullen auf.\n";
            diff = 16 - tmp.length();
            for (int i = 0; i < diff; i++) {
                tmp.push_back('\0');
            }
            cout << endl;
        }

        for (int i = 0; i < 16; i++) {
            arr[i] = tmp[i];
        }
        cout << endl;

    }
}

void myAES::enterKlartext() {
    enterValues(klartext, "Klartext");
}

void myAES::enterSchluessel() {
    enterValues(schluessel, "Schluessel");
}

//</editor-fold>

//<editor-fold defaultstate="collapsed" desc="Set/Get-Methoden">

void myAES::setCiphertext(uchar tmp[16]) {
    for (int i = 0; i < 16; i++) {
        ciphertext[i] = tmp[i];
    }
}

void myAES::setKlartext(uchar tmp[16]) {
    for (int i = 0; i < 16; i++) {
        klartext[i] = tmp[i];
    }
}

void myAES::setSchluessel(uchar tmp[16]) {
    for (int i = 0; i < 16; i++) {
        schluessel[i] = tmp[i];
    }
}

uchar* myAES::getSchluessel() {
    return schluessel;
}

uchar* myAES::getCiphertext() {
    return ciphertext;
}

uchar* myAES::getKlartext() {
    return klartext;
}

//</editor-fold>

myCBC.h


#ifndef MYCBC_H
#define	MYCBC_H
#include "myAES.h"
#include <vector>
class myCBC {
public:
    // Konstruktoren / Destruktoren
    myCBC();
    virtual ~myCBC();
    
    //CBC
    void crypt(bool);
    void decrypt(bool);
    
    // Set/Get-Methoden
    void setKey(uchar[16]);
    void setIV(uchar[16]);
    void setKlartext(vector<uchar>);
    void setCiphertext(vector<uchar>);
    vector<uchar> getKlartext();
    vector<uchar> getCiphertext();
    uchar* getSchluessel();
    uchar* getIV();
    
    // Manuelle Eingabe
    void enterKey();
    void enterIV();
    void enterKlartext();
    
private:
    uchar iv[16];
    uchar key[16];
    vector<uchar> klartext;
    vector<uchar> ciphertext;
};

myCBC.cpp


#include "myCBC.h"
#include <math.h>
#include <iostream>
#include <iomanip>

using namespace std;

uchar* myCBC::getSchluessel() {
    return key;
}

vector<uchar> myCBC::getKlartext() {
    return klartext;
}

void enterValue(uchar arr[], string name) {
    string tmp = "";
    int diff = 0;
    cout << name << ": (16 Zeichen):";
    if (cin >> tmp) {

        if (tmp.length() > 16) {
            cerr << "\nWerte fuer den" << name << " zu groß. Trenne nach 16 Zeichen ab.\n(";
            for (int i = 0; i < tmp.length(); i++) {
                if (i == 16) {
                    cerr << " | ";
                }
                cerr << tmp.at(i);
            }
            cout << ")" << endl;
        }

        if (tmp.length() < 16) {
            cerr << "\nWert fuer den Klartext zu klein. Fuelle mit Nullen auf.\n";
            diff = 16 - tmp.length();
            for (int i = 0; i < diff; i++) {
                tmp.push_back('\0');
            }
            cout << endl;
        }

        for (int i = 0; i < 16; i++) {
            arr[i] = tmp[i];
        }
        cout << endl;

    }
}

void myCBC::enterKey() {
    enterValue(key, "Schluessel");
}

void myCBC::enterIV() {
    enterValue(iv, "Initialisierungsvektor");
}

void myCBC::enterKlartext() {
    klartext.clear();
    string tmp = "";
    cout << "Klartext (Beliebig viele Zeichen):";
    if (cin >> tmp) {
        for (int i = 0; i < tmp.size(); i++) {
            klartext.push_back(tmp[i]);
        }
        cout << endl;
    }

    if (tmp.size() % 16 != 0) {
        cerr << "\nLetzter Klartext-Block nicht vollstaendig. Fuelle mit Nullen auf.\n";
        for (int i = 0; i < 16 - tmp.size() % 16; i++) {
            klartext.push_back('\0');
        }
        cout << endl;
    }
}

myCBC::myCBC() {

    // Default Parameter
    uchar newKey[16] = {0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c};
    uchar newIV[16] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F};
    uchar newKlartext[16] = {0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a};

    // Schluessel setzen
    for (int i = 0; i < 16; i++) {
        key[i] = newKey[i];
    }

    //IV setzen
    for (int i = 0; i < 16; i++) {
        iv[i] = newIV[i];
    }

    // Klartext setzen
    for (int i = 0; i < 16; i++) {
        klartext.push_back(newKlartext[i]);
    }
}

vector<uchar> myCBC::getCiphertext() {
    return ciphertext;
}

void myCBC::decrypt(bool print) {
    klartext.clear();

    uchar tmp_iv[16];
    for (int j = 0; j < 16; j++) {
        tmp_iv[j] = iv[j];
    }
    for (int i = 0; i < ciphertext.size() / 16; i++) {

        myAES a1;

        //Übergabe - Array
        uchar tmp[16];
        for (int k = 0; k < 16; k++) {
            tmp[k] = ciphertext[k + 16 * i];
        }

        // Ciphertext
        a1.setCiphertext(tmp);

        // Schluessel
        a1.setSchluessel(key);

        // decrypt
        a1.decrypt(false);

        // Resultat mit IV addieren / XOR
        for (int f = 0; f < 16; f++) {
            a1.getKlartext()[f] = a1.getKlartext()[f]^tmp_iv[f];
        }

        // Neuen IV festlegen und Klartext eintragen
        for (int l = 0; l < 16; l++) {
            tmp_iv[l] = a1.getCiphertext()[l];
            klartext.push_back(a1.getKlartext()[l]);
        }
    }
}

void myCBC::crypt(bool print) {
    ciphertext.clear();
    uchar tmp_iv[16];
    for (int i = 0; i < 16; i++) {
        tmp_iv[i] = iv[i];
    }

    for (int i = 0; i < klartext.size() / 16; i++) {

        myAES a1;
        a1.setSchluessel(key);

        //XOR in Übergabe - Array
        uchar tmp[16];
        for (int j = 0; j < 16; j++) {
            tmp[j] = klartext[j + 16 * i]^tmp_iv[j];
        }

        // Klartext
        a1.setKlartext(tmp);

        // crypt
        a1.crypt(false);


        for (int j = 0; j < 16; j++) {
            tmp_iv[j] = a1.getCiphertext()[j];
            ciphertext.push_back(a1.getCiphertext()[j]);
        }
    }
}

void myCBC::setKlartext(vector<uchar> kt) {
    // Padding mit 0
    if (kt.size() > klartext.size()) {
        int diff = kt.size() - klartext.size();
        for (int i = 0; i < diff; i++) {
            klartext.push_back(0x00);
        }
    }

    // Werte übertragen
    for (int i = 0; i < kt.size(); i++) {
        klartext.at(i) = kt.at(i);
    }
}

void myCBC::setIV(uchar tmp[16]) {
    for (int i = 0; i < 16; i++) {
        iv[i] = tmp[i];
    }
}

void myCBC::setKey(uchar tmp[16]) {
    for (int i = 0; i < 16; i++) {
        key[i] = tmp[i];
    }
}

myCBC::~myCBC() {
}

myECB.h


#ifndef MYECB_H
#define	MYECB_H

#include "myAES.h"
#include <vector>
class myECB {
public:
    // Konstruktoren / Destruktoren
    myECB();
    virtual ~myECB();
    
    //CBC
    void crypt(bool);
    void decrypt(bool);
    
    // Set/Get-Methoden
    void setKey(uchar[16]);
    void setKlartext(vector<uchar>);
    void setCiphertext(vector<uchar>);
    vector<uchar> getKlartext();
    vector<uchar> getCiphertext();
    uchar* getSchluessel();
    
    // Manuelle Eingabe
    void enterKey();    
    void enterKlartext();

private:
    uchar key[16];
    vector<uchar> klartext;
    vector<uchar> ciphertext;

};

#endif	/* MYECB_H */

myECB.cpp


#include "myECB.h"
#include <iomanip>
#include <iostream>

void myECB::enterKey() {
    string tmp = "";
    int diff = 0;
    cout << "Schluessel (16 Zeichen):";
    if (cin >> tmp) {

        if (tmp.length() > 16) {
            cerr << "\nWerte fuer den Schluessel zu groß. Trenne nach 16 Zeichen ab.\n(";
            for (int i = 0; i < tmp.length(); i++) {
                if (i == 16) {
                    cerr << " | ";
                }
                cerr << tmp.at(i);
            }
            cout << ")" << endl;
        }

        if (tmp.length() < 16) {
            cerr << "\nWert fuer den Klartext zu klein. Fuelle mit Nullen auf.\n";
            diff = 16 - tmp.length();
            for (int i = 0; i < diff; i++) {
                tmp.push_back('\0');
            }
            cout << endl;
        }

        for (int i = 0; i < 16; i++) {
            key[i] = tmp[i];
        }
        cout << endl;
    }
}

vector<uchar> myECB::getKlartext() {
    return klartext;
}

void myECB::enterKlartext() {
    klartext.clear();
    string tmp = "";
    cout << "Klartext (Beliebig viele Zeichen):";
    if (cin >> tmp) {
        for (int i = 0; i < tmp.size(); i++) {
            klartext.push_back(tmp[i]);
        }
        cout << endl;
    }

    if (tmp.size() % 16 != 0) {
        cerr << "\nLetzter Klartext-Block nicht vollstaendig. Fuelle mit Nullen auf.\n";
        for (int i = 0; i < 16 - tmp.size() % 16; i++) {
            klartext.push_back('\0');
        }
        cout << endl;
    }
}

myECB::myECB() {

    // Default Parameter
    uchar newKey[16] = {0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c};
    uchar newKlartext[16] = {0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a};

    // Schluessel setzen
    for (int i = 0; i < 16; i++) {
        key[i] = newKey[i];
    }

    // Klartext setzen
    for (int i = 0; i < 16; i++) {
        klartext.push_back(newKlartext[i]);
    }
}

vector<uchar> myECB::getCiphertext() {
    return ciphertext;
}

void myECB::decrypt(bool print) {
    klartext.clear();

    for (int i = 0; i < ciphertext.size() / 16; i++) {

        myAES a1;

        //Übergabe - Array
        uchar tmp[16];
        for (int j = 0; j < 16; j++) {
            tmp[j] = ciphertext[j + 16 * i];
        }

        // Ciphertext
        a1.setCiphertext(tmp);

        // Schluessel
        a1.setSchluessel(key);

        // crypt
        a1.decrypt(false);

        // Resultat mit IV addieren
        for (int j = 0; j < 16; j++) {
            klartext.push_back(a1.getKlartext()[j]);
        }
    }
}

void myECB::crypt(bool print) {
    ciphertext.clear();

    for (int i = 0; i < klartext.size() / 16; i++) {

        myAES a1;
        a1.setSchluessel(key);

        //XOR in Übergabe - Array
        uchar tmp[16];
        for (int j = 0; j < 16; j++) {
            tmp[j] = klartext[j + 16 * i]; //^tmp_iv[j];
        }

        // Klartext
        a1.setKlartext(tmp);

        // crypt
        a1.crypt(false);


        for (int j = 0; j < 16; j++) {
            ciphertext.push_back(a1.getCiphertext()[j]);
        }
    }
}

void myECB::setKlartext(vector<uchar> kt) {
    if (kt.size() > klartext.size()) {
        int diff = kt.size() - klartext.size();
        for (int i = 0; i < diff; i++) {
            klartext.push_back(0x00);
        }
    }
    for (int i = 0; i < kt.size(); i++) {
        klartext.at(i) = kt.at(i);
    }
}

void myECB::setKey(uchar tmp[16]) {
    for (int i = 0; i < 16; i++) {
        key[i] = tmp[i];
    }
}

myECB::~myECB() {
}

myGUI.h


#ifndef MYGUI_H
#define	MYGUI_H

#include <iostream>
#include "myCBC.h"
#include "myECB.h"

class myGUI {
public:
    // Menu
    myGUI();
    void menuAES();
    void menuCBC();
    void menuECB();
    // Tests
    bool checkAES();
    bool checkCBC();
    bool checkECB();
    virtual ~myGUI();
private:
};

#endif	/* MYGUI_H */

myGUI.cpp


//Präprozessor-Direktiven
#include "support.h"
#include "myGUI.h"
#include <vector>
#include <iostream>
#include  <iomanip>


//Namensbereich Auflösung
using namespace std;

// <editor-fold defaultstate="collapsed" desc="Methoden bzgl. AES">

bool myGUI::checkAES() {

    bool returnValue = false;

    // Testvektoren
    uchar schluessel[16] = {0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c};
    uchar klartext_1[16] = {0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a};
    uchar klartext_2[16] = {0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c, 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51};
    uchar klartext_3[16] = {0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11, 0xe5, 0xfb, 0xc1, 0x19, 0x1a, 0x0a, 0x52, 0xef};
    uchar cipher_1[16] = {0x3a, 0xd7, 0x7b, 0xb4, 0x0d, 0x7a, 0x36, 0x60, 0xa8, 0x9e, 0xca, 0xf3, 0x24, 0x66, 0xef, 0x97};
    uchar cipher_2[16] = {0xf5, 0xd3, 0xd5, 0x85, 0x03, 0xb9, 0x69, 0x9d, 0xe7, 0x85, 0x89, 0x5a, 0x96, 0xfd, 0xba, 0xaf};
    uchar cipher_3[16] = {0x43, 0xb1, 0xcd, 0x7f, 0x59, 0x8e, 0xce, 0x23, 0x88, 0x1b, 0x00, 0xe3, 0xed, 0x03, 0x06, 0x88};

    // Test#1
    myAES aes1;
    aes1.setKlartext(klartext_1);
    aes1.setSchluessel(schluessel);
    aes1.crypt(false);

    // Test#2
    myAES aes2;
    aes2.setKlartext(klartext_2);
    aes2.setSchluessel(schluessel);
    aes2.crypt(false);

    // Test#3
    myAES aes3;
    aes3.setKlartext(klartext_3);
    aes3.setSchluessel(schluessel);
    aes3.crypt(false);

    // Prüfung
    bool isWorking = areEqual(aes3.getCiphertext(), cipher_3) && areEqual(aes2.getCiphertext(), cipher_2) && areEqual(aes1.getCiphertext(), cipher_1);
    if (isWorking) {
        returnValue = true;
    } else {

        returnValue = false;
    }
    return returnValue;
}

void myGUI::menuAES() {

    // Variablen initialisieren
    bool run = true;
    unsigned int lowest = 1;
    unsigned int end = 4;
    int input = end;

    // aes initialisieren und verschlüsseln
    myAES aes;
    aes.crypt(false);

    //Menu Eingabe
    while (run) {
        cout << "\nBitte waehlen sie aus:\n";
        cout << "(1) Text verschluesseln \n";
        cout << "(2) Text und Schluessel eingeben \n";
        cout << "(3) Text entschluesseln \n";
        cout << "(4) Zurueck\n";
        cout << "> ";

        // Eingabe überprüfen
        input = validatedInput(lowest, end);

        // Auswahl
        if (input == 1) {
            aes.crypt(true);
            printMatrix(aes.getKlartext(), "Klartext");
            printMatrix(aes.getSchluessel(), "Schluessel");
            printMatrix(aes.getCiphertext(), "Cipher");
        }
        if (input == 2) {
            aes.enterKlartext();
            aes.enterSchluessel();
            aes.crypt(true);
            printMatrix(aes.getKlartext(), "Klartext");
            printMatrix(aes.getSchluessel(), "Schluessel");
            printMatrix(aes.getCiphertext(), "Cipher");
        }
        if (input == 3) {
            aes.decrypt(true);
            printMatrix(aes.getCiphertext(), "Cipher");
            printMatrix(aes.getSchluessel(), "Schluessel");
            printMatrix(aes.getKlartext(), "Klartext");
        }
        if (input == end) {
            run = false;
        }
        if (input == -1) {

            cerr << "Ungueltige Eingabe getätigt.\nBitte nochmal eingeben.\n";
            cout << endl;
        }
    }
}

// </editor-fold>

// <editor-fold defaultstate="collapsed" desc="Methoden bzgl. CBC">

bool myGUI::checkCBC() {
    bool returnValue = false;

    // Test #1  - 16 Byte Testvektoren
    uchar keyB[16] = {0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c};
    uchar ivB[16] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F};
    uchar klartextB1[16] = {0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a};
    uchar ciphertextB1[16] = {0x76, 0x49, 0xab, 0xac, 0x81, 0x19, 0xb2, 0x46, 0xce, 0xe9, 0x8e, 0x9b, 0x12, 0xe9, 0x19, 0x7d};

    // Container 
    vector<uchar> cipherB1;
    vector<uchar> ktB;

    // Container füllen
    for (int i = 0; i < 16; i++) {
        ktB.push_back(klartextB1[i]);
        cipherB1.push_back(ciphertextB1[i]);
    }

    // cbc intialisieren
    myCBC cbcB;
    cbcB.setKey(keyB);
    cbcB.setIV(ivB);
    cbcB.setKlartext(ktB);

    // Verschlüsseln
    cbcB.crypt(false);

    // Test#2 - 32 Byte Testvektoren
    uchar klartextA1[16] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f};
    uchar klartextA2[16] = {0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f};
    uchar ivA[16] = {0x56, 0x2e, 0x17, 0x99, 0x6d, 0x09, 0x3d, 0x28, 0xdd, 0xb3, 0xba, 0x69, 0x5a, 0x2e, 0x6f, 0x58};
    uchar keyA[16] = {0xc2, 0x86, 0x69, 0x6d, 0x88, 0x7c, 0x9a, 0xa0, 0x61, 0x1b, 0xbb, 0x3e, 0x20, 0x25, 0xa4, 0x5a};
    uchar ciphertextA1[16] = {0xd2, 0x96, 0xcd, 0x94, 0xc2, 0xcc, 0xcf, 0x8a, 0x3a, 0x86, 0x30, 0x28, 0xb5, 0xe1, 0xdc, 0x0a};
    uchar ciphertextA2[16] = {0x75, 0x86, 0x60, 0x2d, 0x25, 0x3c, 0xff, 0xf9, 0x1b, 0x82, 0x66, 0xbe, 0xa6, 0xd6, 0x1a, 0xb1};

    // Container
    vector<uchar> cipherA1;
    vector<uchar> test;

    // Container füllen
    for (int i = 0; i < 16; i++) {
        test.push_back(klartextA1[i]);
        cipherA1.push_back(ciphertextA1[i]);
    }

    for (int i = 0; i < 16; i++) {
        test.push_back(klartextA2[i]);
        cipherA1.push_back(ciphertextA2[i]);
    }

    // cbc initialisieren
    myCBC cbcA;
    cbcA.setKey(keyA);
    cbcA.setIV(ivA);
    cbcA.setKlartext(test);

    // Verschlüsseln
    cbcA.crypt(false);

    //Prüfung auf Korrektheit
    bool isWorking = areEqual(cbcA.getCiphertext(), cipherA1) && areEqual(cbcB.getCiphertext(), cipherB1);

    if (isWorking) {
        returnValue = true;
    } else {
        returnValue = false;
    }
    return returnValue;
}

void myGUI::menuCBC() {

    // cbc mit Standard Werten initialisieren
    myCBC cbc;
    cbc.crypt(false);

    // Variablen initialisieren
    bool run = true;
    unsigned int lowest = 1;
    unsigned int end = 5;
    int input = end;

    //Menu Eingabe
    while (run) {
        cout << "\nBitte waehlen sie aus:\n";
        cout << "(1) Text verschluesseln \n";
        cout << "(2) Text und Schluessel eingeben \n";
        cout << "(3) Bild ver- und entschluesseln\n";
        cout << "(4) Text entschluesseln\n";
        cout << "(5) Zurueck\n";
        cout << "> ";

        // Überprüfe Eingabe
        input = validatedInput(lowest, end);

        // Auswahl
        if (input == 1) {
            cbc.crypt(true);
            printMatrix(cbc.getKlartext(), "Klartext");
            printMatrix(cbc.getSchluessel(), "Schluessel");
            printMatrix(cbc.getCiphertext(), "Cipher");
        }
        if (input == 2) {
            cbc.enterIV();
            cbc.enterKey();
            cbc.enterKlartext();
            cbc.crypt(true);
            printMatrix(cbc.getKlartext(), "Klartext");
            printMatrix(cbc.getSchluessel(), "Schluessel");
            printMatrix(cbc.getCiphertext(), "Cipher");
        }
        if (input == 3) {
            //Fülle Vektor mit Punkten
            vector<uchar> myImg;
            fillImage(myImg);

            // Gebe Klartext aus
            printImage(myImg);

            // Setze Klartext, verschlüssle und gebe Cipher aus
            cbc.setKlartext(myImg);
            cbc.crypt(false);
            printImage(cbc.getCiphertext());

            // Entschlüssle und gebe Klartext aus
            cbc.decrypt(false);
            printImage(cbc.getKlartext());
        }
        if (input == 4) {
            cbc.decrypt(true);
            printMatrix(cbc.getCiphertext(), "Cipher");
            printMatrix(cbc.getSchluessel(), "Schluessel");
            printMatrix(cbc.getKlartext(), "Klartext");
        }
        if (input == end) {
            run = false;
        }
        if (input == -1) {
            cerr << "Ungueltige Eingabe getätigt.\nBitte nochmal eingeben.\n";
            cout << endl;
        }
    }

}

// </editor-fold>

// <editor-fold defaultstate="collapsed" desc="Methoden bzgl. ECB">

bool myGUI::checkECB() {
    bool returnValue = false;

    //16 Byte Testvektoren
    uchar schluessel[16] = {0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c};

    uchar klartext_1[16] = {0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a};
    uchar klartext_2[16] = {0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c, 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51};
    uchar klartext_3[16] = {0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11, 0xe5, 0xfb, 0xc1, 0x19, 0x1a, 0x0a, 0x52, 0xef};

    uchar cipher_1[16] = {0x3a, 0xd7, 0x7b, 0xb4, 0x0d, 0x7a, 0x36, 0x60, 0xa8, 0x9e, 0xca, 0xf3, 0x24, 0x66, 0xef, 0x97};
    uchar cipher_2[16] = {0xf5, 0xd3, 0xd5, 0x85, 0x03, 0xb9, 0x69, 0x9d, 0xe7, 0x85, 0x89, 0x5a, 0x96, 0xfd, 0xba, 0xaf};
    uchar cipher_3[16] = {0x43, 0xb1, 0xcd, 0x7f, 0x59, 0x8e, 0xce, 0x23, 0x88, 0x1b, 0x00, 0xe3, 0xed, 0x03, 0x06, 0x88};

    // Container
    vector<uchar> cipherB1;
    vector<uchar> ktB;

    // Fülle Container mit Block 1
    for (int i = 0; i < 16; i++) {
        ktB.push_back(klartext_1[i]);
        cipherB1.push_back(cipher_1[i]);
    }

    // Fülle Container mit Block 2
    for (int i = 0; i < 16; i++) {
        ktB.push_back(klartext_2[i]);
        cipherB1.push_back(cipher_2[i]);
    }

    // Fülle Container mit Block 3
    for (int i = 0; i < 16; i++) {
        ktB.push_back(klartext_3[i]);
        cipherB1.push_back(cipher_3[i]);
    }

    // Verschlüssele mit Hilfe des Schlüssels und den 3 Blöcken
    myECB ecb;
    ecb.setKey(schluessel);
    ecb.setKlartext(ktB);
    ecb.crypt(false);

    //Prüfung auf Gleichheit
    bool isWorking = areEqual(ecb.getCiphertext(), cipherB1);
    if (isWorking) {
        returnValue = true;
    } else {
        returnValue = false;
    }
    return returnValue;
}

void myGUI::menuECB() {


    //Initialisiere ecb mit Standard-Werten
    myECB ecb;
    ecb.crypt(false);

    //Initialisiere Eingabe-Variablen 
    bool run = true;
    unsigned int lowest = 1;
    unsigned int end = 5;
    int input = end;

    //Menu Eingabe
    while (run) {

        cout << "\nBitte waehlen sie aus:\n";
        cout << "(1) Text verschluesseln \n";
        cout << "(2) Text und Schluessel eingeben \n";
        cout << "(3) Bild ver- und entschluesseln\n";
        cout << "(4) Text entschluesseln\n";
        cout << "(5) Zurueck\n";
        cout << "> ";

        // Prüfe Eingabe
        input = validatedInput(lowest, end);

        // Auswahl
        if (input == 1) {
            ecb.crypt(true);
        }
        if (input == 2) {
            ecb.enterKey();
            ecb.enterKlartext();
            ecb.crypt(true);
        }
        if (input == 3) {
            // Erstelle Vektor mit Bildpunkten
            vector<uchar> myImg;
            fillImage(myImg);

            // Gebe Klartext aus
            printImage(myImg);
            ecb.setKlartext(myImg);

            // Verschlpsseln und Gebe Cipher aus
            ecb.crypt(false);
            printImage(ecb.getCiphertext());

            // Entschlüsseln und Klartext ausgeben
            ecb.decrypt(false);
            printImage(ecb.getKlartext());
        }
        if (input == 4) {
            ecb.decrypt(true);
        }
        if (input == end) {
            run = false;
        }
        if (input == -1) {
            cerr << "Ungueltige Eingabe getätigt.\nBitte nochmal eingeben.\n";
            cout << endl;
        }
    }

}

// </editor-fold>

// <editor-fold defaultstate="collapsed" desc="Konstrukturen und Destruktoren">

myGUI::myGUI() {
    //Menu-Variablen

    unsigned int lowest = 1;
    unsigned int end = 4;
    int input = end;
    bool run = true;

    //Start
    cout << "#### Kryptographie Sommersemester 2013 ####\n";
    cout << "Nils Rogmann (725915) und Maximilian Krieg (725922)\n";

    // Begrüßung und Information
    cout << "\nHerzlich willkommen.\n";
    cout << "Das Programm wird nun mit Hilfe von Testvektoren geprueft.\n";

    // AES Check
    cout << "\nAES:\t\t";
    if (checkAES()) {
        cout << "OK";
    } else {
        cerr << "Fehler";
    }

    // CBC Check
    cout << "\nAES mit CBC:\t";
    if (checkCBC()) {
        cout << "OK";
    } else {
        cerr << "Fehler";
    }


    // ECB Check
    cout << "\nAES mit ECB:\t";
    if (checkECB()) {
        cout << "OK";
    } else {
        cerr << "Fehler";
    }

    cout << endl;

    //Menu Eingabe
    while (run) {
        cout << "\nBitte waehlen sie aus:\n";
        cout << "(1) AES\n";
        cout << "(2) AES mit CBC\n";
        cout << "(3) AES mit ECB\n";
        cout << "(4) Programm beenden\n";
        cout << "> ";

        // Prüfe Eingabe auf Gültigkeit
        input = validatedInput(lowest, end);

        // Aufrufe
        if (input == 1) {
            cout << "#### AES ####\n";
            menuAES();
            cout << endl;
        }

        if (input == 2) {
            cout << "#### AES mit CBC ####\n";
            menuCBC();
            cout << endl;
        }


        if (input == 3) {
            cout << "#### AES mit ECB ####\n";
            menuECB();
            cout << endl;
        }

        // Fehler
        if (input == -1) {
            cerr << "Ungueltige Eingabe getätigt.\nBitte nochmal eingeben.\n";
            cout << endl;
        }

        // Beenden
        if (input == end) {

            cout << "Programm wird beendet.\n";
            run = false;
            cout << endl;
        }
    }
}//myGUI

myGUI::~myGUI() {
}//~myGUI

// </editor-fold>

support.h


#include <iostream>
#include <iomanip>
#include <vector>
using namespace std;
typedef unsigned char uchar;

void printMatrix(vector<uchar> v, string name) {
    cout << name << ": \n";

    int add =0;
    for (int j = 0; j < v.size()/16; j++) {
        for (int i = 0; i < 4; i++) {
            cout << hex << setfill('0') << setw(2) << nouppercase << (int) v[i+add] << " ";
            cout << hex << setfill('0') << setw(2) << nouppercase << (int) v[i + 4+add] << " ";
            cout << hex << setfill('0') << setw(2) << nouppercase << (int) v[i + 8+add] << " ";
            cout << hex << setfill('0') << setw(2) << nouppercase << (int) v[i + 12+add] << " ";
            cout << endl;
        }
        add=add+16;
        cout << endl;
    }
    cout << endl;
}

void printMatrix(uchar v[16], string name) {
    cout << name << ": \n";
    for (int i = 0; i < 4; i++) {
        cout << hex << setfill('0') << setw(2) << nouppercase << (int) v[i] << " ";
        cout << hex << setfill('0') << setw(2) << nouppercase << (int) v[i + 4] << " ";
        cout << hex << setfill('0') << setw(2) << nouppercase << (int) v[i + 8] << " ";
        cout << hex << setfill('0') << setw(2) << nouppercase << (int) v[i + 12] << " ";
        cout << endl;
    }
    cout << endl;

    /*
    for (int i=0;i<16;i++)
        cout << hex<<(int) v[i];
     * */
}

int validatedInput(unsigned int lowest, unsigned int highest) {
    int tmp = 0;
    cin.clear();
    if (cin >> tmp) {//Eingabe ist in Ordnung
        cout << endl;
        if (tmp >= lowest && tmp <= highest) {//Eingabe liegt in den Parametern

            return tmp;
        }
    } else {
        // Falsche Inhalte verwerfen und Status zurücksetzen
        string trash = "";
        cin.clear();
        std::getline(std::cin, trash);
    }
    return -1;
}

// 16x16 Matrix ausgeben

void printImage(vector<uchar> myImg) {
    int add = 0;
    for (int j = 0; j < 4; j++) {
        for (int i = 0; i < 4; i++) {
            for (int k = 0; k <= 60; k) {
                cout << hex << setfill('0') << setw(2) << nouppercase << (int) myImg.at(i + k + add) << " ";
                k = k + 4;
            }
            cout << endl;
        }

        add = add + 64;
    }
    cout << endl << endl;
}

// 16x16 Matrix füllen

void fillImage(vector<uchar>& v) {
    // Alles auf 0 setzen
    // Außer den Inneren bereich, diesen auf 1
    for (int y = 0; y < 16; y++) {
        for (int x = 0; x < 16; x++) {
            if (y == 5 || y == 6 || y == 9 || y == 10)
                v.push_back(0x1);
            else {
                v.push_back(0x0);
            }
        }
    }

    //Manuell Randpunkte des Kreises setzen
    v[19] = 0x1;
    v[22] = 0x1;
    v[23] = 0x1;
    v[26] = 0x1;
    v[27] = 0x1;
    v[30] = 0x1;
    v[31] = 0x1;
    v[34] = 0x1;
    v[35] = 0x1;
    v[38] = 0x1;
    v[39] = 0x1;
    v[42] = 0x1;
    v[43] = 0x1;
    v[47] = 0x1;
    v[73] = 0x1;
    v[74] = 0x1;
    v[75] = 0x1;
    v[76] = 0x1;
    v[77] = 0x1;
    v[78] = 0x1;
    v[79] = 0x1;
    v[112] = 0x1;
    v[113] = 0x1;
    v[114] = 0x1;
    v[115] = 0x1;
    v[117] = 0x1;
    v[118] = 0x1;
    v[119] = 0x1;
    v[136] = 0x1;
    v[137] = 0x1;
    v[138] = 0x1;
    v[140] = 0x1;
    v[141] = 0x1;
    v[142] = 0x1;
    v[143] = 0x1;
    v[176] = 0x1;
    v[177] = 0x1;
    v[178] = 0x1;
    v[179] = 0x1;
    v[180] = 0x1;
    v[181] = 0x1;
    v[182] = 0x1;
    v[208] = 0x1;
    v[212] = 0x1;
    v[213] = 0x1;
    v[216] = 0x1;
    v[217] = 0x1;
    v[220] = 0x1;
    v[221] = 0x1;
    v[224] = 0x1;
    v[225] = 0x1;
    v[228] = 0x1;
    v[229] = 0x1;
    v[232] = 0x1;
    v[233] = 0x1;
    v[236] = 0x1;
}

// Gleichheitsprüfung

template<class T>
bool areEqual(T arr1, T arr2) {
    bool tmp = false;
    for (int i = 0; i < 16; i++) {
        if (arr1[i] == arr2[i]) {
            tmp = true;
        } else {
            cout << hex << arr1[i] << "!=" << arr2[i] << endl;
            tmp = false;
            break;
        }
    }
    return tmp;
}

Schreiben Sie einen Kommentar

Ihre E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert

Diese Website verwendet Akismet, um Spam zu reduzieren. Erfahren Sie, wie Ihre Kommentardaten verarbeitet werden.

'); } cout << endl; } for (int i = 0; i < 16; i++) { arr[i] = tmp[i]; } cout << endl; } } void myCBC::enterKey() { enterValue(key, "Schluessel"); } void myCBC::enterIV() { enterValue(iv, "Initialisierungsvektor"); } void myCBC::enterKlartext() { klartext.clear(); string tmp = ""; cout << "Klartext (Beliebig viele Zeichen):"; if (cin >> tmp) { for (int i = 0; i < tmp.size(); i++) { klartext.push_back(tmp[i]); } cout << endl; } if (tmp.size() % 16 != 0) { cerr << "\nLetzter Klartext-Block nicht vollstaendig. Fuelle mit Nullen auf.\n"; for (int i = 0; i < 16 - tmp.size() % 16; i++) { klartext.push_back('
Menu Close

Kryptologie (Praktikum 4)

Skript-AnfangKryptouebung3 – Seite 1
Skript-EndeKryptouebung3 – Seite 1

main.cpp


#include <cstdlib>
#include <iostream>
#include <iomanip>
#include "myGUI.h"


// Using-Deklarationen
using namespace std;

int main(int argc, char** argv) {
    //Start GUI
    myGUI gui;
}// main

myAES.h


#ifndef MYAES_H
#define	MYAES_H

#include <iostream>

using namespace std;
// Typedefs
typedef unsigned char uchar;

class myAES {
public:
    // Konstruktoren/Destruktoren
    myAES();
    virtual ~myAES();

    // Manuelle Eingabe
    void enterKlartext();
    void enterSchluessel();

    // Set/Get-Methoden
    void setKlartext(uchar[16]);
    void setSchluessel(uchar[16]);
    void setCiphertext(uchar[16]);
    uchar* getKlartext();
    uchar* getSchluessel();
    uchar* getCiphertext();

    // Crypt
    void crypt(bool);
    void mixcolumns();
    void shiftrows();
    void schluesselexpansion(uchar[][44], int, int, int);
    void rotword(uchar[], int);
    uchar mix(uchar, unsigned int);
    void subbytes(uchar [], uchar [], int);
    
    // Decrypt
    void decrypt(bool);
    uchar gmul(uchar, uchar);
    void invert_mixcolumns();
    void invert_shiftrows();    
    
private:
    uchar klartext[16];
    uchar schluessel[16];
    uchar ciphertext[16];
};



#endif	/* MYAES_H */

myAES.cpp


#include "myAES.h"

using namespace std;

//<editor-fold defaultstate="collapsed" desc="Boxen">

unsigned char Sbox[256] = {//  s-box
    0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
    0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
    0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
    0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
    0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,
    0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
    0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,
    0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,
    0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
    0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
    0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,
    0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
    0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
    0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
    0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
    0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16
};

unsigned char sbox_inverse[256] = {
    0x52, 0x09, 0x6A, 0xD5, 0x30, 0x36, 0xA5, 0x38, 0xBF, 0x40, 0xA3, 0x9E, 0x81, 0xF3, 0xD7, 0xFB,
    0x7C, 0xE3, 0x39, 0x82, 0x9B, 0x2F, 0xFF, 0x87, 0x34, 0x8E, 0x43, 0x44, 0xC4, 0xDE, 0xE9, 0xCB,
    0x54, 0x7B, 0x94, 0x32, 0xA6, 0xC2, 0x23, 0x3D, 0xEE, 0x4C, 0x95, 0x0B, 0x42, 0xFA, 0xC3, 0x4E,
    0x08, 0x2E, 0xA1, 0x66, 0x28, 0xD9, 0x24, 0xB2, 0x76, 0x5B, 0xA2, 0x49, 0x6D, 0x8B, 0xD1, 0x25,
    0x72, 0xF8, 0xF6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xD4, 0xA4, 0x5C, 0xCC, 0x5D, 0x65, 0xB6, 0x92,
    0x6C, 0x70, 0x48, 0x50, 0xFD, 0xED, 0xB9, 0xDA, 0x5E, 0x15, 0x46, 0x57, 0xA7, 0x8D, 0x9D, 0x84,
    0x90, 0xD8, 0xAB, 0x00, 0x8C, 0xBC, 0xD3, 0x0A, 0xF7, 0xE4, 0x58, 0x05, 0xB8, 0xB3, 0x45, 0x06,
    0xD0, 0x2C, 0x1E, 0x8F, 0xCA, 0x3F, 0x0F, 0x02, 0xC1, 0xAF, 0xBD, 0x03, 0x01, 0x13, 0x8A, 0x6B,
    0x3A, 0x91, 0x11, 0x41, 0x4F, 0x67, 0xDC, 0xEA, 0x97, 0xF2, 0xCF, 0xCE, 0xF0, 0xB4, 0xE6, 0x73,
    0x96, 0xAC, 0x74, 0x22, 0xE7, 0xAD, 0x35, 0x85, 0xE2, 0xF9, 0x37, 0xE8, 0x1C, 0x75, 0xDF, 0x6E,
    0x47, 0xF1, 0x1A, 0x71, 0x1D, 0x29, 0xC5, 0x89, 0x6F, 0xB7, 0x62, 0x0E, 0xAA, 0x18, 0xBE, 0x1B,
    0xFC, 0x56, 0x3E, 0x4B, 0xC6, 0xD2, 0x79, 0x20, 0x9A, 0xDB, 0xC0, 0xFE, 0x78, 0xCD, 0x5A, 0xF4,
    0x1F, 0xDD, 0xA8, 0x33, 0x88, 0x07, 0xC7, 0x31, 0xB1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xEC, 0x5F,
    0x60, 0x51, 0x7F, 0xA9, 0x19, 0xB5, 0x4A, 0x0D, 0x2D, 0xE5, 0x7A, 0x9F, 0x93, 0xC9, 0x9C, 0xEF,
    0xA0, 0xE0, 0x3B, 0x4D, 0xAE, 0x2A, 0xF5, 0xB0, 0xC8, 0xEB, 0xBB, 0x3C, 0x83, 0x53, 0x99, 0x61,
    0x17, 0x2B, 0x04, 0x7E, 0xBA, 0x77, 0xD6, 0x26, 0xE1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0C, 0x7D
};

unsigned char Rcon[256] = {
    0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a,
    0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39,
    0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a,
    0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8,
    0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef,
    0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc,
    0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b,
    0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3,
    0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94,
    0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20,
    0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35,
    0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f,
    0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04,
    0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63,
    0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd,
    0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d
};
//</editor-fold>

//<editor-fold defaultstate="collapsed" desc="AES-Methoden">

void myAES::subbytes(uchar sbox[], uchar tmp[], int arrSize) {
    for (int i = 0; i < arrSize; i++) {
        tmp[i] = sbox[tmp[i]];
    }
}// subbytes

uchar myAES::mix(uchar byte, unsigned int mixvalue) {
    unsigned char retValue;
    switch (mixvalue) {
        case 1:
            retValue = byte;
            break;
        case 2:
            retValue = byte << 1;
            if (byte & 0x80) {
                retValue = retValue ^ 0x1b;
            }
            break;
        case 3:
            retValue = byte << 1;
            if (byte & 0x80) {
                retValue = retValue ^ 0x1b;
            }
            retValue = retValue^byte;
            break;
    }
    return retValue;
}

void addRoundKey(uchar array[], uchar matrix[][44], int iReihe, int iSpalte, int iRunde) {
    int pos = 0;
    for (int i = iRunde * 4; i < ((iRunde * 4) + 4) && i < iSpalte; i++) {
        for (int k = 0; k < iReihe; k++) {
            array[pos] = array[pos] ^ matrix[k][i];
            pos++;
        }
    }
}// addroundkey

void myAES::rotword(uchar column[], int iReihe) {
    uchar tmp = column[0];
    for (int i = 1; i < iReihe; i++) {
        column[i - 1] = column[i];
    }
    column[iReihe - 1] = tmp;
} // rotword

void myAES::schluesselexpansion(uchar matrix[][44], int iReihe, int iSpalte, int iLaenge) {
    // Alle Spalten durchlaufen
    int pos = 0;

    for (int i = 0; i < iSpalte; i++) {
        if (i < 4) { // Schluessel in erste vier Spalten kopieren
            for (int k = 0; k < iReihe && pos < iLaenge; k++) {
                matrix[k][i] = schluessel[pos];
                pos++;
                //cout << hex << "matrix[" << k << "][" << i << "] = " << (int) matrix[k][i] << endl;
            }
        } else { // i > 4
            if (i % 4 == 0) {// erste Spalte eines Schluessels
                // Spalte in Hilfsarray kopieren
                uchar tmp[iReihe]; // i-1
                uchar tmp2[iReihe]; // i-4
                for (int k = 0; k < iReihe; k++) {
                    tmp[k] = matrix[k][i - 1];
                    tmp2[k] = matrix[k][i - 4];
                }

                rotword(tmp, iReihe);

                subbytes(Sbox, tmp, iReihe);

                // Spalte[i-4] XOR subbytes[rotword[i-i]
                for (int k = 0; k < iReihe; k++) {
                    tmp[k] = tmp[k] ^ tmp2[k];
                }

                // tmp[0] XOR (i/4)
                tmp[0] = tmp[0] ^ Rcon[i / iReihe];

                // tmp[k] an Spalte[k][i] kopieren
                for (int k = 0; k < iReihe; k++) {
                    matrix[k][i] = tmp[k];
                }

            } else {
                //cout << "i " << i << endl;
                for (int k = 0; k < iReihe; k++) {
                    matrix[k][i] = matrix[k][i - 4] ^ matrix[k][i - 1];
                }
            }
        }
    }
}// schluesselexpansion

void myAES::shiftrows() {
    uchar copys[16] = {};

    //reihe 1   
    copys[0] = ciphertext[0];
    copys[4] = ciphertext[4];
    copys[8] = ciphertext[8];
    copys[12] = ciphertext[12];

    //reihe 2
    copys[1] = ciphertext[5];
    copys[5] = ciphertext[9];
    copys[9] = ciphertext[13];
    copys[13] = ciphertext[1];

    // reihe 3
    copys[2] = ciphertext[10];
    copys[6] = ciphertext[14];
    copys[10] = ciphertext[2];
    copys[14] = ciphertext[6];

    //reihe 4
    copys[3] = ciphertext[15];
    copys[7] = ciphertext[3];
    copys[11] = ciphertext[7];
    copys[15] = ciphertext[11];

    //umschreiben   
    for (int i = 0; i < 16; i++) {
        ciphertext[i] = copys[i];
    }
}// shiftrows

void myAES::mixcolumns() {
    for (int i = 0; i < 4; i++) {
        uchar sj0 = mix(ciphertext[i * 4], 2)^mix(ciphertext[i * 4 + 1], 3)^mix(ciphertext[i * 4 + 2], 1)^mix(ciphertext[i * 4 + 3], 1);
        uchar sj1 = mix(ciphertext[i * 4], 1)^mix(ciphertext[i * 4 + 1], 2)^mix(ciphertext[i * 4 + 2], 3)^mix(ciphertext[i * 4 + 3], 1);
        uchar sj2 = mix(ciphertext[i * 4], 1)^mix(ciphertext[i * 4 + 1], 1)^mix(ciphertext[i * 4 + 2], 2)^mix(ciphertext[i * 4 + 3], 3);
        uchar sj3 = mix(ciphertext[i * 4], 3)^mix(ciphertext[i * 4 + 1], 1)^mix(ciphertext[i * 4 + 2], 1)^mix(ciphertext[i * 4 + 3], 2);
        ciphertext[i * 4] = sj0;
        ciphertext[i * 4 + 1] = sj1;
        ciphertext[i * 4 + 2] = sj2;
        ciphertext[i * 4 + 3] = sj3;
    }
}// mixcolumns

void myAES::crypt(bool output) {

    // Parameter
    int iRunde = 10;
    int iLaenge = 16;

    // Überschreibe ciphertext um diesen fortan zu verwenden
    for (int i = 0; i < 16; i++) {
        ciphertext[i] = klartext[i];
    }

    // Arraygroesse dynamisch bestimmen
    int arrSize = sizeof (ciphertext) / sizeof (ciphertext[0]);

    // Zwischenspeicherung der Rundenschluessel
    int iReihe = 4;
    int iSpalte = 4 * (iRunde + 1);
    uchar carrRundenschluessel[4][44];

    // Schluessel expandieren
    schluesselexpansion(carrRundenschluessel, iReihe, iSpalte, iLaenge);

    // Vorrunde
    for (int k = 0; k < iLaenge; k++) {
        ciphertext[k] = ciphertext[k] ^ schluessel[k];
    }

    // Durchlaufen der Runden
    for (int i = 1; i < iRunde + 1; i++) {

        // S-Box
        subbytes(Sbox, ciphertext, arrSize);

        // Shift Rows
        shiftrows();

        // Mix Columns
        if (i != (iRunde)) { // kein MixColumns in der letzten Runde
            mixcolumns();
        }

        // Rundenschlüssel addieren
        addRoundKey(ciphertext, carrRundenschluessel, iReihe, iSpalte, i);

    }
}

void myAES::invert_shiftrows() {
    uchar copys[16] = {};

    //reihe 1   
    copys[0] = klartext[0];
    copys[4] = klartext[4];
    copys[8] = klartext[8];
    copys[12] = klartext[12];

    //reihe 2
    copys[1] = klartext[13];
    copys[13] = klartext[9];
    copys[9] = klartext[5];
    copys[5] = klartext[1];

    // reihe 3   
    copys[6] = klartext[14];
    copys[2] = klartext[10];
    copys[14] = klartext[6];
    copys[10] = klartext[2];

    //reihe 4
    copys[11] = klartext[15];
    copys[7] = klartext[11];
    copys[3] = klartext[7];
    copys[15] = klartext[3];

    //umschreiben   
    for (int i = 0; i < 16; i++) {
        klartext[i] = copys[i];
    }
}// invert_shiftrows

void myAES::invert_mixcolumns() {
    for (int i = 0; i < 4; i++) {
        uchar sj0 = gmul(klartext[i * 4], 14)^gmul(klartext[i * 4 + 1], 11)^gmul(klartext[i * 4 + 2], 13)^gmul(klartext[i * 4 + 3], 9);
        uchar sj1 = gmul(klartext[i * 4], 9)^gmul(klartext[i * 4 + 1], 14)^gmul(klartext[i * 4 + 2], 11)^gmul(klartext[i * 4 + 3], 13);
        uchar sj2 = gmul(klartext[i * 4], 13)^gmul(klartext[i * 4 + 1], 9)^gmul(klartext[i * 4 + 2], 14)^gmul(klartext[i * 4 + 3], 11);
        uchar sj3 = gmul(klartext[i * 4], 11)^gmul(klartext[i * 4 + 1], 13)^gmul(klartext[i * 4 + 2], 9)^gmul(klartext[i * 4 + 3], 14);
        klartext[i * 4] = sj0;
        klartext[i * 4 + 1] = sj1;
        klartext[i * 4 + 2] = sj2;
        klartext[i * 4 + 3] = sj3;
    }
}

uchar myAES::gmul(uchar a, uchar b) {
    unsigned char p = 0;
    unsigned char hi;

    for (int i = 0; i < 8; ++i) {
        if ((b & 1) == 1)
            p ^= a;
        hi = (a & 0x80);
        a <<= 1;
        if (hi == 0x80)
            a ^= 0x1b;
        b >>= 1;
    }
    return p;
}

void myAES::decrypt(bool output) {

    // Parameter
    int iRunde = 10;
    int iLaenge = 16;


    // Überschreibe klartext um diesen fortan zu verwenden
    for (int i = 0; i < 16; i++) {
        klartext[i] = ciphertext[i];
    }

    // Arraygroesse dynamisch bestimmen
    int arrSize = sizeof (klartext) / sizeof (klartext[0]);

    // Zwischenspeicherung der Rundenschluessel
    int iReihe = 4;
    int iSpalte = 4 * (iRunde + 1);
    uchar carrRundenschluessel[4][44];

    // Schluessel expandieren
    schluesselexpansion(carrRundenschluessel, iReihe, iSpalte, iLaenge);

    // "neue" Vorrunde
    addRoundKey(klartext, carrRundenschluessel, iReihe, iSpalte, 10);

    // Durchlaufen der Runden
    for (int i = 9; i > 0; i--) {

        // Shift Rows
        invert_shiftrows();

        // S-Box
        subbytes(sbox_inverse, klartext, arrSize);

        // Rundenschlüssel addieren
        addRoundKey(klartext, carrRundenschluessel, iReihe, iSpalte, i);

        // Mix Columns
        if (i != 10) { // kein MixColumns in der letzten Runde
            invert_mixcolumns();
        }
    }

    // Letzte Runde
    invert_shiftrows();
    subbytes(sbox_inverse, klartext, arrSize);

    for (int k = 0; k < iLaenge; k++) {
        klartext[k] = klartext[k] ^ schluessel[k];
    }
}// decrypt

//</editor-fold>

//<editor-fold defaultstate="collapsed" desc="Konstruktur/Destruktor">

myAES::myAES() {
    uchar kt[16] = {0x61, 0x62, 0x62, 0x69, 0x6c, 0x64, 0x75, 0x6e, 0x67, 0x73, 0x6d, 0x61, 0x74, 0x72, 0x69, 0x78};
    uchar s[16] = {0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31};
    //uchar c[16] = {0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31};
    for (int i = 0; i < 16; i++) {
        schluessel[i] = s[i];
        klartext[i] = kt[i];
    }
}

myAES::~myAES() {
}
//</editor-fold>

//<editor-fold defaultstate="collapsed" desc="Manuelle Eingabe">

void enterValues(uchar arr[], string name) {
    string tmp = "";
    int diff = 0;
    cout << name << ": (16 Zeichen):";
    if (cin >> tmp) {

        if (tmp.length() > 16) {
            cerr << "\nWerte fuer den" << name << " zu groß. Trenne nach 16 Zeichen ab.\n(";
            for (int i = 0; i < tmp.length(); i++) {
                if (i == 16) {
                    cerr << " | ";
                }
                cerr << tmp.at(i);
            }
            cout << ")" << endl;
        }

        if (tmp.length() < 16) {
            cerr << "\nWert fuer den Klartext zu klein. Fuelle mit Nullen auf.\n";
            diff = 16 - tmp.length();
            for (int i = 0; i < diff; i++) {
                tmp.push_back('\0');
            }
            cout << endl;
        }

        for (int i = 0; i < 16; i++) {
            arr[i] = tmp[i];
        }
        cout << endl;

    }
}

void myAES::enterKlartext() {
    enterValues(klartext, "Klartext");
}

void myAES::enterSchluessel() {
    enterValues(schluessel, "Schluessel");
}

//</editor-fold>

//<editor-fold defaultstate="collapsed" desc="Set/Get-Methoden">

void myAES::setCiphertext(uchar tmp[16]) {
    for (int i = 0; i < 16; i++) {
        ciphertext[i] = tmp[i];
    }
}

void myAES::setKlartext(uchar tmp[16]) {
    for (int i = 0; i < 16; i++) {
        klartext[i] = tmp[i];
    }
}

void myAES::setSchluessel(uchar tmp[16]) {
    for (int i = 0; i < 16; i++) {
        schluessel[i] = tmp[i];
    }
}

uchar* myAES::getSchluessel() {
    return schluessel;
}

uchar* myAES::getCiphertext() {
    return ciphertext;
}

uchar* myAES::getKlartext() {
    return klartext;
}

//</editor-fold>

myCBC.h


#ifndef MYCBC_H
#define	MYCBC_H
#include "myAES.h"
#include <vector>
class myCBC {
public:
    // Konstruktoren / Destruktoren
    myCBC();
    virtual ~myCBC();
    
    //CBC
    void crypt(bool);
    void decrypt(bool);
    
    // Set/Get-Methoden
    void setKey(uchar[16]);
    void setIV(uchar[16]);
    void setKlartext(vector<uchar>);
    void setCiphertext(vector<uchar>);
    vector<uchar> getKlartext();
    vector<uchar> getCiphertext();
    uchar* getSchluessel();
    uchar* getIV();
    
    // Manuelle Eingabe
    void enterKey();
    void enterIV();
    void enterKlartext();
    
private:
    uchar iv[16];
    uchar key[16];
    vector<uchar> klartext;
    vector<uchar> ciphertext;
};

myCBC.cpp


#include "myCBC.h"
#include <math.h>
#include <iostream>
#include <iomanip>

using namespace std;

uchar* myCBC::getSchluessel() {
    return key;
}

vector<uchar> myCBC::getKlartext() {
    return klartext;
}

void enterValue(uchar arr[], string name) {
    string tmp = "";
    int diff = 0;
    cout << name << ": (16 Zeichen):";
    if (cin >> tmp) {

        if (tmp.length() > 16) {
            cerr << "\nWerte fuer den" << name << " zu groß. Trenne nach 16 Zeichen ab.\n(";
            for (int i = 0; i < tmp.length(); i++) {
                if (i == 16) {
                    cerr << " | ";
                }
                cerr << tmp.at(i);
            }
            cout << ")" << endl;
        }

        if (tmp.length() < 16) {
            cerr << "\nWert fuer den Klartext zu klein. Fuelle mit Nullen auf.\n";
            diff = 16 - tmp.length();
            for (int i = 0; i < diff; i++) {
                tmp.push_back('\0');
            }
            cout << endl;
        }

        for (int i = 0; i < 16; i++) {
            arr[i] = tmp[i];
        }
        cout << endl;

    }
}

void myCBC::enterKey() {
    enterValue(key, "Schluessel");
}

void myCBC::enterIV() {
    enterValue(iv, "Initialisierungsvektor");
}

void myCBC::enterKlartext() {
    klartext.clear();
    string tmp = "";
    cout << "Klartext (Beliebig viele Zeichen):";
    if (cin >> tmp) {
        for (int i = 0; i < tmp.size(); i++) {
            klartext.push_back(tmp[i]);
        }
        cout << endl;
    }

    if (tmp.size() % 16 != 0) {
        cerr << "\nLetzter Klartext-Block nicht vollstaendig. Fuelle mit Nullen auf.\n";
        for (int i = 0; i < 16 - tmp.size() % 16; i++) {
            klartext.push_back('\0');
        }
        cout << endl;
    }
}

myCBC::myCBC() {

    // Default Parameter
    uchar newKey[16] = {0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c};
    uchar newIV[16] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F};
    uchar newKlartext[16] = {0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a};

    // Schluessel setzen
    for (int i = 0; i < 16; i++) {
        key[i] = newKey[i];
    }

    //IV setzen
    for (int i = 0; i < 16; i++) {
        iv[i] = newIV[i];
    }

    // Klartext setzen
    for (int i = 0; i < 16; i++) {
        klartext.push_back(newKlartext[i]);
    }
}

vector<uchar> myCBC::getCiphertext() {
    return ciphertext;
}

void myCBC::decrypt(bool print) {
    klartext.clear();

    uchar tmp_iv[16];
    for (int j = 0; j < 16; j++) {
        tmp_iv[j] = iv[j];
    }
    for (int i = 0; i < ciphertext.size() / 16; i++) {

        myAES a1;

        //Übergabe - Array
        uchar tmp[16];
        for (int k = 0; k < 16; k++) {
            tmp[k] = ciphertext[k + 16 * i];
        }

        // Ciphertext
        a1.setCiphertext(tmp);

        // Schluessel
        a1.setSchluessel(key);

        // decrypt
        a1.decrypt(false);

        // Resultat mit IV addieren / XOR
        for (int f = 0; f < 16; f++) {
            a1.getKlartext()[f] = a1.getKlartext()[f]^tmp_iv[f];
        }

        // Neuen IV festlegen und Klartext eintragen
        for (int l = 0; l < 16; l++) {
            tmp_iv[l] = a1.getCiphertext()[l];
            klartext.push_back(a1.getKlartext()[l]);
        }
    }
}

void myCBC::crypt(bool print) {
    ciphertext.clear();
    uchar tmp_iv[16];
    for (int i = 0; i < 16; i++) {
        tmp_iv[i] = iv[i];
    }

    for (int i = 0; i < klartext.size() / 16; i++) {

        myAES a1;
        a1.setSchluessel(key);

        //XOR in Übergabe - Array
        uchar tmp[16];
        for (int j = 0; j < 16; j++) {
            tmp[j] = klartext[j + 16 * i]^tmp_iv[j];
        }

        // Klartext
        a1.setKlartext(tmp);

        // crypt
        a1.crypt(false);


        for (int j = 0; j < 16; j++) {
            tmp_iv[j] = a1.getCiphertext()[j];
            ciphertext.push_back(a1.getCiphertext()[j]);
        }
    }
}

void myCBC::setKlartext(vector<uchar> kt) {
    // Padding mit 0
    if (kt.size() > klartext.size()) {
        int diff = kt.size() - klartext.size();
        for (int i = 0; i < diff; i++) {
            klartext.push_back(0x00);
        }
    }

    // Werte übertragen
    for (int i = 0; i < kt.size(); i++) {
        klartext.at(i) = kt.at(i);
    }
}

void myCBC::setIV(uchar tmp[16]) {
    for (int i = 0; i < 16; i++) {
        iv[i] = tmp[i];
    }
}

void myCBC::setKey(uchar tmp[16]) {
    for (int i = 0; i < 16; i++) {
        key[i] = tmp[i];
    }
}

myCBC::~myCBC() {
}

myECB.h


#ifndef MYECB_H
#define	MYECB_H

#include "myAES.h"
#include <vector>
class myECB {
public:
    // Konstruktoren / Destruktoren
    myECB();
    virtual ~myECB();
    
    //CBC
    void crypt(bool);
    void decrypt(bool);
    
    // Set/Get-Methoden
    void setKey(uchar[16]);
    void setKlartext(vector<uchar>);
    void setCiphertext(vector<uchar>);
    vector<uchar> getKlartext();
    vector<uchar> getCiphertext();
    uchar* getSchluessel();
    
    // Manuelle Eingabe
    void enterKey();    
    void enterKlartext();

private:
    uchar key[16];
    vector<uchar> klartext;
    vector<uchar> ciphertext;

};

#endif	/* MYECB_H */

myECB.cpp


#include "myECB.h"
#include <iomanip>
#include <iostream>

void myECB::enterKey() {
    string tmp = "";
    int diff = 0;
    cout << "Schluessel (16 Zeichen):";
    if (cin >> tmp) {

        if (tmp.length() > 16) {
            cerr << "\nWerte fuer den Schluessel zu groß. Trenne nach 16 Zeichen ab.\n(";
            for (int i = 0; i < tmp.length(); i++) {
                if (i == 16) {
                    cerr << " | ";
                }
                cerr << tmp.at(i);
            }
            cout << ")" << endl;
        }

        if (tmp.length() < 16) {
            cerr << "\nWert fuer den Klartext zu klein. Fuelle mit Nullen auf.\n";
            diff = 16 - tmp.length();
            for (int i = 0; i < diff; i++) {
                tmp.push_back('\0');
            }
            cout << endl;
        }

        for (int i = 0; i < 16; i++) {
            key[i] = tmp[i];
        }
        cout << endl;
    }
}

vector<uchar> myECB::getKlartext() {
    return klartext;
}

void myECB::enterKlartext() {
    klartext.clear();
    string tmp = "";
    cout << "Klartext (Beliebig viele Zeichen):";
    if (cin >> tmp) {
        for (int i = 0; i < tmp.size(); i++) {
            klartext.push_back(tmp[i]);
        }
        cout << endl;
    }

    if (tmp.size() % 16 != 0) {
        cerr << "\nLetzter Klartext-Block nicht vollstaendig. Fuelle mit Nullen auf.\n";
        for (int i = 0; i < 16 - tmp.size() % 16; i++) {
            klartext.push_back('\0');
        }
        cout << endl;
    }
}

myECB::myECB() {

    // Default Parameter
    uchar newKey[16] = {0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c};
    uchar newKlartext[16] = {0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a};

    // Schluessel setzen
    for (int i = 0; i < 16; i++) {
        key[i] = newKey[i];
    }

    // Klartext setzen
    for (int i = 0; i < 16; i++) {
        klartext.push_back(newKlartext[i]);
    }
}

vector<uchar> myECB::getCiphertext() {
    return ciphertext;
}

void myECB::decrypt(bool print) {
    klartext.clear();

    for (int i = 0; i < ciphertext.size() / 16; i++) {

        myAES a1;

        //Übergabe - Array
        uchar tmp[16];
        for (int j = 0; j < 16; j++) {
            tmp[j] = ciphertext[j + 16 * i];
        }

        // Ciphertext
        a1.setCiphertext(tmp);

        // Schluessel
        a1.setSchluessel(key);

        // crypt
        a1.decrypt(false);

        // Resultat mit IV addieren
        for (int j = 0; j < 16; j++) {
            klartext.push_back(a1.getKlartext()[j]);
        }
    }
}

void myECB::crypt(bool print) {
    ciphertext.clear();

    for (int i = 0; i < klartext.size() / 16; i++) {

        myAES a1;
        a1.setSchluessel(key);

        //XOR in Übergabe - Array
        uchar tmp[16];
        for (int j = 0; j < 16; j++) {
            tmp[j] = klartext[j + 16 * i]; //^tmp_iv[j];
        }

        // Klartext
        a1.setKlartext(tmp);

        // crypt
        a1.crypt(false);


        for (int j = 0; j < 16; j++) {
            ciphertext.push_back(a1.getCiphertext()[j]);
        }
    }
}

void myECB::setKlartext(vector<uchar> kt) {
    if (kt.size() > klartext.size()) {
        int diff = kt.size() - klartext.size();
        for (int i = 0; i < diff; i++) {
            klartext.push_back(0x00);
        }
    }
    for (int i = 0; i < kt.size(); i++) {
        klartext.at(i) = kt.at(i);
    }
}

void myECB::setKey(uchar tmp[16]) {
    for (int i = 0; i < 16; i++) {
        key[i] = tmp[i];
    }
}

myECB::~myECB() {
}

myGUI.h


#ifndef MYGUI_H
#define	MYGUI_H

#include <iostream>
#include "myCBC.h"
#include "myECB.h"

class myGUI {
public:
    // Menu
    myGUI();
    void menuAES();
    void menuCBC();
    void menuECB();
    // Tests
    bool checkAES();
    bool checkCBC();
    bool checkECB();
    virtual ~myGUI();
private:
};

#endif	/* MYGUI_H */

myGUI.cpp


//Präprozessor-Direktiven
#include "support.h"
#include "myGUI.h"
#include <vector>
#include <iostream>
#include  <iomanip>


//Namensbereich Auflösung
using namespace std;

// <editor-fold defaultstate="collapsed" desc="Methoden bzgl. AES">

bool myGUI::checkAES() {

    bool returnValue = false;

    // Testvektoren
    uchar schluessel[16] = {0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c};
    uchar klartext_1[16] = {0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a};
    uchar klartext_2[16] = {0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c, 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51};
    uchar klartext_3[16] = {0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11, 0xe5, 0xfb, 0xc1, 0x19, 0x1a, 0x0a, 0x52, 0xef};
    uchar cipher_1[16] = {0x3a, 0xd7, 0x7b, 0xb4, 0x0d, 0x7a, 0x36, 0x60, 0xa8, 0x9e, 0xca, 0xf3, 0x24, 0x66, 0xef, 0x97};
    uchar cipher_2[16] = {0xf5, 0xd3, 0xd5, 0x85, 0x03, 0xb9, 0x69, 0x9d, 0xe7, 0x85, 0x89, 0x5a, 0x96, 0xfd, 0xba, 0xaf};
    uchar cipher_3[16] = {0x43, 0xb1, 0xcd, 0x7f, 0x59, 0x8e, 0xce, 0x23, 0x88, 0x1b, 0x00, 0xe3, 0xed, 0x03, 0x06, 0x88};

    // Test#1
    myAES aes1;
    aes1.setKlartext(klartext_1);
    aes1.setSchluessel(schluessel);
    aes1.crypt(false);

    // Test#2
    myAES aes2;
    aes2.setKlartext(klartext_2);
    aes2.setSchluessel(schluessel);
    aes2.crypt(false);

    // Test#3
    myAES aes3;
    aes3.setKlartext(klartext_3);
    aes3.setSchluessel(schluessel);
    aes3.crypt(false);

    // Prüfung
    bool isWorking = areEqual(aes3.getCiphertext(), cipher_3) && areEqual(aes2.getCiphertext(), cipher_2) && areEqual(aes1.getCiphertext(), cipher_1);
    if (isWorking) {
        returnValue = true;
    } else {

        returnValue = false;
    }
    return returnValue;
}

void myGUI::menuAES() {

    // Variablen initialisieren
    bool run = true;
    unsigned int lowest = 1;
    unsigned int end = 4;
    int input = end;

    // aes initialisieren und verschlüsseln
    myAES aes;
    aes.crypt(false);

    //Menu Eingabe
    while (run) {
        cout << "\nBitte waehlen sie aus:\n";
        cout << "(1) Text verschluesseln \n";
        cout << "(2) Text und Schluessel eingeben \n";
        cout << "(3) Text entschluesseln \n";
        cout << "(4) Zurueck\n";
        cout << "> ";

        // Eingabe überprüfen
        input = validatedInput(lowest, end);

        // Auswahl
        if (input == 1) {
            aes.crypt(true);
            printMatrix(aes.getKlartext(), "Klartext");
            printMatrix(aes.getSchluessel(), "Schluessel");
            printMatrix(aes.getCiphertext(), "Cipher");
        }
        if (input == 2) {
            aes.enterKlartext();
            aes.enterSchluessel();
            aes.crypt(true);
            printMatrix(aes.getKlartext(), "Klartext");
            printMatrix(aes.getSchluessel(), "Schluessel");
            printMatrix(aes.getCiphertext(), "Cipher");
        }
        if (input == 3) {
            aes.decrypt(true);
            printMatrix(aes.getCiphertext(), "Cipher");
            printMatrix(aes.getSchluessel(), "Schluessel");
            printMatrix(aes.getKlartext(), "Klartext");
        }
        if (input == end) {
            run = false;
        }
        if (input == -1) {

            cerr << "Ungueltige Eingabe getätigt.\nBitte nochmal eingeben.\n";
            cout << endl;
        }
    }
}

// </editor-fold>

// <editor-fold defaultstate="collapsed" desc="Methoden bzgl. CBC">

bool myGUI::checkCBC() {
    bool returnValue = false;

    // Test #1  - 16 Byte Testvektoren
    uchar keyB[16] = {0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c};
    uchar ivB[16] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F};
    uchar klartextB1[16] = {0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a};
    uchar ciphertextB1[16] = {0x76, 0x49, 0xab, 0xac, 0x81, 0x19, 0xb2, 0x46, 0xce, 0xe9, 0x8e, 0x9b, 0x12, 0xe9, 0x19, 0x7d};

    // Container 
    vector<uchar> cipherB1;
    vector<uchar> ktB;

    // Container füllen
    for (int i = 0; i < 16; i++) {
        ktB.push_back(klartextB1[i]);
        cipherB1.push_back(ciphertextB1[i]);
    }

    // cbc intialisieren
    myCBC cbcB;
    cbcB.setKey(keyB);
    cbcB.setIV(ivB);
    cbcB.setKlartext(ktB);

    // Verschlüsseln
    cbcB.crypt(false);

    // Test#2 - 32 Byte Testvektoren
    uchar klartextA1[16] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f};
    uchar klartextA2[16] = {0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f};
    uchar ivA[16] = {0x56, 0x2e, 0x17, 0x99, 0x6d, 0x09, 0x3d, 0x28, 0xdd, 0xb3, 0xba, 0x69, 0x5a, 0x2e, 0x6f, 0x58};
    uchar keyA[16] = {0xc2, 0x86, 0x69, 0x6d, 0x88, 0x7c, 0x9a, 0xa0, 0x61, 0x1b, 0xbb, 0x3e, 0x20, 0x25, 0xa4, 0x5a};
    uchar ciphertextA1[16] = {0xd2, 0x96, 0xcd, 0x94, 0xc2, 0xcc, 0xcf, 0x8a, 0x3a, 0x86, 0x30, 0x28, 0xb5, 0xe1, 0xdc, 0x0a};
    uchar ciphertextA2[16] = {0x75, 0x86, 0x60, 0x2d, 0x25, 0x3c, 0xff, 0xf9, 0x1b, 0x82, 0x66, 0xbe, 0xa6, 0xd6, 0x1a, 0xb1};

    // Container
    vector<uchar> cipherA1;
    vector<uchar> test;

    // Container füllen
    for (int i = 0; i < 16; i++) {
        test.push_back(klartextA1[i]);
        cipherA1.push_back(ciphertextA1[i]);
    }

    for (int i = 0; i < 16; i++) {
        test.push_back(klartextA2[i]);
        cipherA1.push_back(ciphertextA2[i]);
    }

    // cbc initialisieren
    myCBC cbcA;
    cbcA.setKey(keyA);
    cbcA.setIV(ivA);
    cbcA.setKlartext(test);

    // Verschlüsseln
    cbcA.crypt(false);

    //Prüfung auf Korrektheit
    bool isWorking = areEqual(cbcA.getCiphertext(), cipherA1) && areEqual(cbcB.getCiphertext(), cipherB1);

    if (isWorking) {
        returnValue = true;
    } else {
        returnValue = false;
    }
    return returnValue;
}

void myGUI::menuCBC() {

    // cbc mit Standard Werten initialisieren
    myCBC cbc;
    cbc.crypt(false);

    // Variablen initialisieren
    bool run = true;
    unsigned int lowest = 1;
    unsigned int end = 5;
    int input = end;

    //Menu Eingabe
    while (run) {
        cout << "\nBitte waehlen sie aus:\n";
        cout << "(1) Text verschluesseln \n";
        cout << "(2) Text und Schluessel eingeben \n";
        cout << "(3) Bild ver- und entschluesseln\n";
        cout << "(4) Text entschluesseln\n";
        cout << "(5) Zurueck\n";
        cout << "> ";

        // Überprüfe Eingabe
        input = validatedInput(lowest, end);

        // Auswahl
        if (input == 1) {
            cbc.crypt(true);
            printMatrix(cbc.getKlartext(), "Klartext");
            printMatrix(cbc.getSchluessel(), "Schluessel");
            printMatrix(cbc.getCiphertext(), "Cipher");
        }
        if (input == 2) {
            cbc.enterIV();
            cbc.enterKey();
            cbc.enterKlartext();
            cbc.crypt(true);
            printMatrix(cbc.getKlartext(), "Klartext");
            printMatrix(cbc.getSchluessel(), "Schluessel");
            printMatrix(cbc.getCiphertext(), "Cipher");
        }
        if (input == 3) {
            //Fülle Vektor mit Punkten
            vector<uchar> myImg;
            fillImage(myImg);

            // Gebe Klartext aus
            printImage(myImg);

            // Setze Klartext, verschlüssle und gebe Cipher aus
            cbc.setKlartext(myImg);
            cbc.crypt(false);
            printImage(cbc.getCiphertext());

            // Entschlüssle und gebe Klartext aus
            cbc.decrypt(false);
            printImage(cbc.getKlartext());
        }
        if (input == 4) {
            cbc.decrypt(true);
            printMatrix(cbc.getCiphertext(), "Cipher");
            printMatrix(cbc.getSchluessel(), "Schluessel");
            printMatrix(cbc.getKlartext(), "Klartext");
        }
        if (input == end) {
            run = false;
        }
        if (input == -1) {
            cerr << "Ungueltige Eingabe getätigt.\nBitte nochmal eingeben.\n";
            cout << endl;
        }
    }

}

// </editor-fold>

// <editor-fold defaultstate="collapsed" desc="Methoden bzgl. ECB">

bool myGUI::checkECB() {
    bool returnValue = false;

    //16 Byte Testvektoren
    uchar schluessel[16] = {0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c};

    uchar klartext_1[16] = {0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a};
    uchar klartext_2[16] = {0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c, 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51};
    uchar klartext_3[16] = {0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11, 0xe5, 0xfb, 0xc1, 0x19, 0x1a, 0x0a, 0x52, 0xef};

    uchar cipher_1[16] = {0x3a, 0xd7, 0x7b, 0xb4, 0x0d, 0x7a, 0x36, 0x60, 0xa8, 0x9e, 0xca, 0xf3, 0x24, 0x66, 0xef, 0x97};
    uchar cipher_2[16] = {0xf5, 0xd3, 0xd5, 0x85, 0x03, 0xb9, 0x69, 0x9d, 0xe7, 0x85, 0x89, 0x5a, 0x96, 0xfd, 0xba, 0xaf};
    uchar cipher_3[16] = {0x43, 0xb1, 0xcd, 0x7f, 0x59, 0x8e, 0xce, 0x23, 0x88, 0x1b, 0x00, 0xe3, 0xed, 0x03, 0x06, 0x88};

    // Container
    vector<uchar> cipherB1;
    vector<uchar> ktB;

    // Fülle Container mit Block 1
    for (int i = 0; i < 16; i++) {
        ktB.push_back(klartext_1[i]);
        cipherB1.push_back(cipher_1[i]);
    }

    // Fülle Container mit Block 2
    for (int i = 0; i < 16; i++) {
        ktB.push_back(klartext_2[i]);
        cipherB1.push_back(cipher_2[i]);
    }

    // Fülle Container mit Block 3
    for (int i = 0; i < 16; i++) {
        ktB.push_back(klartext_3[i]);
        cipherB1.push_back(cipher_3[i]);
    }

    // Verschlüssele mit Hilfe des Schlüssels und den 3 Blöcken
    myECB ecb;
    ecb.setKey(schluessel);
    ecb.setKlartext(ktB);
    ecb.crypt(false);

    //Prüfung auf Gleichheit
    bool isWorking = areEqual(ecb.getCiphertext(), cipherB1);
    if (isWorking) {
        returnValue = true;
    } else {
        returnValue = false;
    }
    return returnValue;
}

void myGUI::menuECB() {


    //Initialisiere ecb mit Standard-Werten
    myECB ecb;
    ecb.crypt(false);

    //Initialisiere Eingabe-Variablen 
    bool run = true;
    unsigned int lowest = 1;
    unsigned int end = 5;
    int input = end;

    //Menu Eingabe
    while (run) {

        cout << "\nBitte waehlen sie aus:\n";
        cout << "(1) Text verschluesseln \n";
        cout << "(2) Text und Schluessel eingeben \n";
        cout << "(3) Bild ver- und entschluesseln\n";
        cout << "(4) Text entschluesseln\n";
        cout << "(5) Zurueck\n";
        cout << "> ";

        // Prüfe Eingabe
        input = validatedInput(lowest, end);

        // Auswahl
        if (input == 1) {
            ecb.crypt(true);
        }
        if (input == 2) {
            ecb.enterKey();
            ecb.enterKlartext();
            ecb.crypt(true);
        }
        if (input == 3) {
            // Erstelle Vektor mit Bildpunkten
            vector<uchar> myImg;
            fillImage(myImg);

            // Gebe Klartext aus
            printImage(myImg);
            ecb.setKlartext(myImg);

            // Verschlpsseln und Gebe Cipher aus
            ecb.crypt(false);
            printImage(ecb.getCiphertext());

            // Entschlüsseln und Klartext ausgeben
            ecb.decrypt(false);
            printImage(ecb.getKlartext());
        }
        if (input == 4) {
            ecb.decrypt(true);
        }
        if (input == end) {
            run = false;
        }
        if (input == -1) {
            cerr << "Ungueltige Eingabe getätigt.\nBitte nochmal eingeben.\n";
            cout << endl;
        }
    }

}

// </editor-fold>

// <editor-fold defaultstate="collapsed" desc="Konstrukturen und Destruktoren">

myGUI::myGUI() {
    //Menu-Variablen

    unsigned int lowest = 1;
    unsigned int end = 4;
    int input = end;
    bool run = true;

    //Start
    cout << "#### Kryptographie Sommersemester 2013 ####\n";
    cout << "Nils Rogmann (725915) und Maximilian Krieg (725922)\n";

    // Begrüßung und Information
    cout << "\nHerzlich willkommen.\n";
    cout << "Das Programm wird nun mit Hilfe von Testvektoren geprueft.\n";

    // AES Check
    cout << "\nAES:\t\t";
    if (checkAES()) {
        cout << "OK";
    } else {
        cerr << "Fehler";
    }

    // CBC Check
    cout << "\nAES mit CBC:\t";
    if (checkCBC()) {
        cout << "OK";
    } else {
        cerr << "Fehler";
    }


    // ECB Check
    cout << "\nAES mit ECB:\t";
    if (checkECB()) {
        cout << "OK";
    } else {
        cerr << "Fehler";
    }

    cout << endl;

    //Menu Eingabe
    while (run) {
        cout << "\nBitte waehlen sie aus:\n";
        cout << "(1) AES\n";
        cout << "(2) AES mit CBC\n";
        cout << "(3) AES mit ECB\n";
        cout << "(4) Programm beenden\n";
        cout << "> ";

        // Prüfe Eingabe auf Gültigkeit
        input = validatedInput(lowest, end);

        // Aufrufe
        if (input == 1) {
            cout << "#### AES ####\n";
            menuAES();
            cout << endl;
        }

        if (input == 2) {
            cout << "#### AES mit CBC ####\n";
            menuCBC();
            cout << endl;
        }


        if (input == 3) {
            cout << "#### AES mit ECB ####\n";
            menuECB();
            cout << endl;
        }

        // Fehler
        if (input == -1) {
            cerr << "Ungueltige Eingabe getätigt.\nBitte nochmal eingeben.\n";
            cout << endl;
        }

        // Beenden
        if (input == end) {

            cout << "Programm wird beendet.\n";
            run = false;
            cout << endl;
        }
    }
}//myGUI

myGUI::~myGUI() {
}//~myGUI

// </editor-fold>

support.h


#include <iostream>
#include <iomanip>
#include <vector>
using namespace std;
typedef unsigned char uchar;

void printMatrix(vector<uchar> v, string name) {
    cout << name << ": \n";

    int add =0;
    for (int j = 0; j < v.size()/16; j++) {
        for (int i = 0; i < 4; i++) {
            cout << hex << setfill('0') << setw(2) << nouppercase << (int) v[i+add] << " ";
            cout << hex << setfill('0') << setw(2) << nouppercase << (int) v[i + 4+add] << " ";
            cout << hex << setfill('0') << setw(2) << nouppercase << (int) v[i + 8+add] << " ";
            cout << hex << setfill('0') << setw(2) << nouppercase << (int) v[i + 12+add] << " ";
            cout << endl;
        }
        add=add+16;
        cout << endl;
    }
    cout << endl;
}

void printMatrix(uchar v[16], string name) {
    cout << name << ": \n";
    for (int i = 0; i < 4; i++) {
        cout << hex << setfill('0') << setw(2) << nouppercase << (int) v[i] << " ";
        cout << hex << setfill('0') << setw(2) << nouppercase << (int) v[i + 4] << " ";
        cout << hex << setfill('0') << setw(2) << nouppercase << (int) v[i + 8] << " ";
        cout << hex << setfill('0') << setw(2) << nouppercase << (int) v[i + 12] << " ";
        cout << endl;
    }
    cout << endl;

    /*
    for (int i=0;i<16;i++)
        cout << hex<<(int) v[i];
     * */
}

int validatedInput(unsigned int lowest, unsigned int highest) {
    int tmp = 0;
    cin.clear();
    if (cin >> tmp) {//Eingabe ist in Ordnung
        cout << endl;
        if (tmp >= lowest && tmp <= highest) {//Eingabe liegt in den Parametern

            return tmp;
        }
    } else {
        // Falsche Inhalte verwerfen und Status zurücksetzen
        string trash = "";
        cin.clear();
        std::getline(std::cin, trash);
    }
    return -1;
}

// 16x16 Matrix ausgeben

void printImage(vector<uchar> myImg) {
    int add = 0;
    for (int j = 0; j < 4; j++) {
        for (int i = 0; i < 4; i++) {
            for (int k = 0; k <= 60; k) {
                cout << hex << setfill('0') << setw(2) << nouppercase << (int) myImg.at(i + k + add) << " ";
                k = k + 4;
            }
            cout << endl;
        }

        add = add + 64;
    }
    cout << endl << endl;
}

// 16x16 Matrix füllen

void fillImage(vector<uchar>& v) {
    // Alles auf 0 setzen
    // Außer den Inneren bereich, diesen auf 1
    for (int y = 0; y < 16; y++) {
        for (int x = 0; x < 16; x++) {
            if (y == 5 || y == 6 || y == 9 || y == 10)
                v.push_back(0x1);
            else {
                v.push_back(0x0);
            }
        }
    }

    //Manuell Randpunkte des Kreises setzen
    v[19] = 0x1;
    v[22] = 0x1;
    v[23] = 0x1;
    v[26] = 0x1;
    v[27] = 0x1;
    v[30] = 0x1;
    v[31] = 0x1;
    v[34] = 0x1;
    v[35] = 0x1;
    v[38] = 0x1;
    v[39] = 0x1;
    v[42] = 0x1;
    v[43] = 0x1;
    v[47] = 0x1;
    v[73] = 0x1;
    v[74] = 0x1;
    v[75] = 0x1;
    v[76] = 0x1;
    v[77] = 0x1;
    v[78] = 0x1;
    v[79] = 0x1;
    v[112] = 0x1;
    v[113] = 0x1;
    v[114] = 0x1;
    v[115] = 0x1;
    v[117] = 0x1;
    v[118] = 0x1;
    v[119] = 0x1;
    v[136] = 0x1;
    v[137] = 0x1;
    v[138] = 0x1;
    v[140] = 0x1;
    v[141] = 0x1;
    v[142] = 0x1;
    v[143] = 0x1;
    v[176] = 0x1;
    v[177] = 0x1;
    v[178] = 0x1;
    v[179] = 0x1;
    v[180] = 0x1;
    v[181] = 0x1;
    v[182] = 0x1;
    v[208] = 0x1;
    v[212] = 0x1;
    v[213] = 0x1;
    v[216] = 0x1;
    v[217] = 0x1;
    v[220] = 0x1;
    v[221] = 0x1;
    v[224] = 0x1;
    v[225] = 0x1;
    v[228] = 0x1;
    v[229] = 0x1;
    v[232] = 0x1;
    v[233] = 0x1;
    v[236] = 0x1;
}

// Gleichheitsprüfung

template<class T>
bool areEqual(T arr1, T arr2) {
    bool tmp = false;
    for (int i = 0; i < 16; i++) {
        if (arr1[i] == arr2[i]) {
            tmp = true;
        } else {
            cout << hex << arr1[i] << "!=" << arr2[i] << endl;
            tmp = false;
            break;
        }
    }
    return tmp;
}

Schreiben Sie einen Kommentar

Ihre E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert

Diese Website verwendet Akismet, um Spam zu reduzieren. Erfahren Sie, wie Ihre Kommentardaten verarbeitet werden.

'); } cout << endl; } } myCBC::myCBC() { // Default Parameter uchar newKey[16] = {0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c}; uchar newIV[16] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F}; uchar newKlartext[16] = {0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a}; // Schluessel setzen for (int i = 0; i < 16; i++) { key[i] = newKey[i]; } //IV setzen for (int i = 0; i < 16; i++) { iv[i] = newIV[i]; } // Klartext setzen for (int i = 0; i < 16; i++) { klartext.push_back(newKlartext[i]); } } vector<uchar> myCBC::getCiphertext() { return ciphertext; } void myCBC::decrypt(bool print) { klartext.clear(); uchar tmp_iv[16]; for (int j = 0; j < 16; j++) { tmp_iv[j] = iv[j]; } for (int i = 0; i < ciphertext.size() / 16; i++) { myAES a1; //Übergabe - Array uchar tmp[16]; for (int k = 0; k < 16; k++) { tmp[k] = ciphertext[k + 16 * i]; } // Ciphertext a1.setCiphertext(tmp); // Schluessel a1.setSchluessel(key); // decrypt a1.decrypt(false); // Resultat mit IV addieren / XOR for (int f = 0; f < 16; f++) { a1.getKlartext()[f] = a1.getKlartext()[f]^tmp_iv[f]; } // Neuen IV festlegen und Klartext eintragen for (int l = 0; l < 16; l++) { tmp_iv[l] = a1.getCiphertext()[l]; klartext.push_back(a1.getKlartext()[l]); } } } void myCBC::crypt(bool print) { ciphertext.clear(); uchar tmp_iv[16]; for (int i = 0; i < 16; i++) { tmp_iv[i] = iv[i]; } for (int i = 0; i < klartext.size() / 16; i++) { myAES a1; a1.setSchluessel(key); //XOR in Übergabe - Array uchar tmp[16]; for (int j = 0; j < 16; j++) { tmp[j] = klartext[j + 16 * i]^tmp_iv[j]; } // Klartext a1.setKlartext(tmp); // crypt a1.crypt(false); for (int j = 0; j < 16; j++) { tmp_iv[j] = a1.getCiphertext()[j]; ciphertext.push_back(a1.getCiphertext()[j]); } } } void myCBC::setKlartext(vector<uchar> kt) { // Padding mit 0 if (kt.size() > klartext.size()) { int diff = kt.size() - klartext.size(); for (int i = 0; i < diff; i++) { klartext.push_back(0x00); } } // Werte übertragen for (int i = 0; i < kt.size(); i++) { klartext.at(i) = kt.at(i); } } void myCBC::setIV(uchar tmp[16]) { for (int i = 0; i < 16; i++) { iv[i] = tmp[i]; } } void myCBC::setKey(uchar tmp[16]) { for (int i = 0; i < 16; i++) { key[i] = tmp[i]; } } myCBC::~myCBC() { }

myECB.h


#ifndef MYECB_H
#define	MYECB_H

#include "myAES.h"
#include <vector>
class myECB {
public:
    // Konstruktoren / Destruktoren
    myECB();
    virtual ~myECB();
    
    //CBC
    void crypt(bool);
    void decrypt(bool);
    
    // Set/Get-Methoden
    void setKey(uchar[16]);
    void setKlartext(vector<uchar>);
    void setCiphertext(vector<uchar>);
    vector<uchar> getKlartext();
    vector<uchar> getCiphertext();
    uchar* getSchluessel();
    
    // Manuelle Eingabe
    void enterKey();    
    void enterKlartext();

private:
    uchar key[16];
    vector<uchar> klartext;
    vector<uchar> ciphertext;

};

#endif	/* MYECB_H */

myECB.cpp


#include "myECB.h"
#include <iomanip>
#include <iostream>
void myECB::enterKey() {
string tmp = "";
int diff = 0;
cout << "Schluessel (16 Zeichen):";
if (cin >> tmp) {
if (tmp.length() > 16) {
cerr << "\nWerte fuer den Schluessel zu groß. Trenne nach 16 Zeichen ab.\n(";
for (int i = 0; i < tmp.length(); i++) {
if (i == 16) {
cerr << " | ";
}
cerr << tmp.at(i);
}
cout << ")" << endl;
}
if (tmp.length() < 16) {
cerr << "\nWert fuer den Klartext zu klein. Fuelle mit Nullen auf.\n";
diff = 16 - tmp.length();
for (int i = 0; i < diff; i++) {
tmp.push_back('
Menu Close

Kryptologie (Praktikum 4)

Skript-AnfangKryptouebung3 – Seite 1
Skript-EndeKryptouebung3 – Seite 1

main.cpp


#include <cstdlib>
#include <iostream>
#include <iomanip>
#include "myGUI.h"


// Using-Deklarationen
using namespace std;

int main(int argc, char** argv) {
    //Start GUI
    myGUI gui;
}// main

myAES.h


#ifndef MYAES_H
#define	MYAES_H

#include <iostream>

using namespace std;
// Typedefs
typedef unsigned char uchar;

class myAES {
public:
    // Konstruktoren/Destruktoren
    myAES();
    virtual ~myAES();

    // Manuelle Eingabe
    void enterKlartext();
    void enterSchluessel();

    // Set/Get-Methoden
    void setKlartext(uchar[16]);
    void setSchluessel(uchar[16]);
    void setCiphertext(uchar[16]);
    uchar* getKlartext();
    uchar* getSchluessel();
    uchar* getCiphertext();

    // Crypt
    void crypt(bool);
    void mixcolumns();
    void shiftrows();
    void schluesselexpansion(uchar[][44], int, int, int);
    void rotword(uchar[], int);
    uchar mix(uchar, unsigned int);
    void subbytes(uchar [], uchar [], int);
    
    // Decrypt
    void decrypt(bool);
    uchar gmul(uchar, uchar);
    void invert_mixcolumns();
    void invert_shiftrows();    
    
private:
    uchar klartext[16];
    uchar schluessel[16];
    uchar ciphertext[16];
};



#endif	/* MYAES_H */

myAES.cpp


#include "myAES.h"

using namespace std;

//<editor-fold defaultstate="collapsed" desc="Boxen">

unsigned char Sbox[256] = {//  s-box
    0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
    0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
    0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
    0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
    0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,
    0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
    0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,
    0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,
    0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
    0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
    0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,
    0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
    0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
    0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
    0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
    0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16
};

unsigned char sbox_inverse[256] = {
    0x52, 0x09, 0x6A, 0xD5, 0x30, 0x36, 0xA5, 0x38, 0xBF, 0x40, 0xA3, 0x9E, 0x81, 0xF3, 0xD7, 0xFB,
    0x7C, 0xE3, 0x39, 0x82, 0x9B, 0x2F, 0xFF, 0x87, 0x34, 0x8E, 0x43, 0x44, 0xC4, 0xDE, 0xE9, 0xCB,
    0x54, 0x7B, 0x94, 0x32, 0xA6, 0xC2, 0x23, 0x3D, 0xEE, 0x4C, 0x95, 0x0B, 0x42, 0xFA, 0xC3, 0x4E,
    0x08, 0x2E, 0xA1, 0x66, 0x28, 0xD9, 0x24, 0xB2, 0x76, 0x5B, 0xA2, 0x49, 0x6D, 0x8B, 0xD1, 0x25,
    0x72, 0xF8, 0xF6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xD4, 0xA4, 0x5C, 0xCC, 0x5D, 0x65, 0xB6, 0x92,
    0x6C, 0x70, 0x48, 0x50, 0xFD, 0xED, 0xB9, 0xDA, 0x5E, 0x15, 0x46, 0x57, 0xA7, 0x8D, 0x9D, 0x84,
    0x90, 0xD8, 0xAB, 0x00, 0x8C, 0xBC, 0xD3, 0x0A, 0xF7, 0xE4, 0x58, 0x05, 0xB8, 0xB3, 0x45, 0x06,
    0xD0, 0x2C, 0x1E, 0x8F, 0xCA, 0x3F, 0x0F, 0x02, 0xC1, 0xAF, 0xBD, 0x03, 0x01, 0x13, 0x8A, 0x6B,
    0x3A, 0x91, 0x11, 0x41, 0x4F, 0x67, 0xDC, 0xEA, 0x97, 0xF2, 0xCF, 0xCE, 0xF0, 0xB4, 0xE6, 0x73,
    0x96, 0xAC, 0x74, 0x22, 0xE7, 0xAD, 0x35, 0x85, 0xE2, 0xF9, 0x37, 0xE8, 0x1C, 0x75, 0xDF, 0x6E,
    0x47, 0xF1, 0x1A, 0x71, 0x1D, 0x29, 0xC5, 0x89, 0x6F, 0xB7, 0x62, 0x0E, 0xAA, 0x18, 0xBE, 0x1B,
    0xFC, 0x56, 0x3E, 0x4B, 0xC6, 0xD2, 0x79, 0x20, 0x9A, 0xDB, 0xC0, 0xFE, 0x78, 0xCD, 0x5A, 0xF4,
    0x1F, 0xDD, 0xA8, 0x33, 0x88, 0x07, 0xC7, 0x31, 0xB1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xEC, 0x5F,
    0x60, 0x51, 0x7F, 0xA9, 0x19, 0xB5, 0x4A, 0x0D, 0x2D, 0xE5, 0x7A, 0x9F, 0x93, 0xC9, 0x9C, 0xEF,
    0xA0, 0xE0, 0x3B, 0x4D, 0xAE, 0x2A, 0xF5, 0xB0, 0xC8, 0xEB, 0xBB, 0x3C, 0x83, 0x53, 0x99, 0x61,
    0x17, 0x2B, 0x04, 0x7E, 0xBA, 0x77, 0xD6, 0x26, 0xE1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0C, 0x7D
};

unsigned char Rcon[256] = {
    0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a,
    0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39,
    0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a,
    0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8,
    0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef,
    0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc,
    0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b,
    0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3,
    0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94,
    0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20,
    0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35,
    0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f,
    0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04,
    0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63,
    0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd,
    0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d
};
//</editor-fold>

//<editor-fold defaultstate="collapsed" desc="AES-Methoden">

void myAES::subbytes(uchar sbox[], uchar tmp[], int arrSize) {
    for (int i = 0; i < arrSize; i++) {
        tmp[i] = sbox[tmp[i]];
    }
}// subbytes

uchar myAES::mix(uchar byte, unsigned int mixvalue) {
    unsigned char retValue;
    switch (mixvalue) {
        case 1:
            retValue = byte;
            break;
        case 2:
            retValue = byte << 1;
            if (byte & 0x80) {
                retValue = retValue ^ 0x1b;
            }
            break;
        case 3:
            retValue = byte << 1;
            if (byte & 0x80) {
                retValue = retValue ^ 0x1b;
            }
            retValue = retValue^byte;
            break;
    }
    return retValue;
}

void addRoundKey(uchar array[], uchar matrix[][44], int iReihe, int iSpalte, int iRunde) {
    int pos = 0;
    for (int i = iRunde * 4; i < ((iRunde * 4) + 4) && i < iSpalte; i++) {
        for (int k = 0; k < iReihe; k++) {
            array[pos] = array[pos] ^ matrix[k][i];
            pos++;
        }
    }
}// addroundkey

void myAES::rotword(uchar column[], int iReihe) {
    uchar tmp = column[0];
    for (int i = 1; i < iReihe; i++) {
        column[i - 1] = column[i];
    }
    column[iReihe - 1] = tmp;
} // rotword

void myAES::schluesselexpansion(uchar matrix[][44], int iReihe, int iSpalte, int iLaenge) {
    // Alle Spalten durchlaufen
    int pos = 0;

    for (int i = 0; i < iSpalte; i++) {
        if (i < 4) { // Schluessel in erste vier Spalten kopieren
            for (int k = 0; k < iReihe && pos < iLaenge; k++) {
                matrix[k][i] = schluessel[pos];
                pos++;
                //cout << hex << "matrix[" << k << "][" << i << "] = " << (int) matrix[k][i] << endl;
            }
        } else { // i > 4
            if (i % 4 == 0) {// erste Spalte eines Schluessels
                // Spalte in Hilfsarray kopieren
                uchar tmp[iReihe]; // i-1
                uchar tmp2[iReihe]; // i-4
                for (int k = 0; k < iReihe; k++) {
                    tmp[k] = matrix[k][i - 1];
                    tmp2[k] = matrix[k][i - 4];
                }

                rotword(tmp, iReihe);

                subbytes(Sbox, tmp, iReihe);

                // Spalte[i-4] XOR subbytes[rotword[i-i]
                for (int k = 0; k < iReihe; k++) {
                    tmp[k] = tmp[k] ^ tmp2[k];
                }

                // tmp[0] XOR (i/4)
                tmp[0] = tmp[0] ^ Rcon[i / iReihe];

                // tmp[k] an Spalte[k][i] kopieren
                for (int k = 0; k < iReihe; k++) {
                    matrix[k][i] = tmp[k];
                }

            } else {
                //cout << "i " << i << endl;
                for (int k = 0; k < iReihe; k++) {
                    matrix[k][i] = matrix[k][i - 4] ^ matrix[k][i - 1];
                }
            }
        }
    }
}// schluesselexpansion

void myAES::shiftrows() {
    uchar copys[16] = {};

    //reihe 1   
    copys[0] = ciphertext[0];
    copys[4] = ciphertext[4];
    copys[8] = ciphertext[8];
    copys[12] = ciphertext[12];

    //reihe 2
    copys[1] = ciphertext[5];
    copys[5] = ciphertext[9];
    copys[9] = ciphertext[13];
    copys[13] = ciphertext[1];

    // reihe 3
    copys[2] = ciphertext[10];
    copys[6] = ciphertext[14];
    copys[10] = ciphertext[2];
    copys[14] = ciphertext[6];

    //reihe 4
    copys[3] = ciphertext[15];
    copys[7] = ciphertext[3];
    copys[11] = ciphertext[7];
    copys[15] = ciphertext[11];

    //umschreiben   
    for (int i = 0; i < 16; i++) {
        ciphertext[i] = copys[i];
    }
}// shiftrows

void myAES::mixcolumns() {
    for (int i = 0; i < 4; i++) {
        uchar sj0 = mix(ciphertext[i * 4], 2)^mix(ciphertext[i * 4 + 1], 3)^mix(ciphertext[i * 4 + 2], 1)^mix(ciphertext[i * 4 + 3], 1);
        uchar sj1 = mix(ciphertext[i * 4], 1)^mix(ciphertext[i * 4 + 1], 2)^mix(ciphertext[i * 4 + 2], 3)^mix(ciphertext[i * 4 + 3], 1);
        uchar sj2 = mix(ciphertext[i * 4], 1)^mix(ciphertext[i * 4 + 1], 1)^mix(ciphertext[i * 4 + 2], 2)^mix(ciphertext[i * 4 + 3], 3);
        uchar sj3 = mix(ciphertext[i * 4], 3)^mix(ciphertext[i * 4 + 1], 1)^mix(ciphertext[i * 4 + 2], 1)^mix(ciphertext[i * 4 + 3], 2);
        ciphertext[i * 4] = sj0;
        ciphertext[i * 4 + 1] = sj1;
        ciphertext[i * 4 + 2] = sj2;
        ciphertext[i * 4 + 3] = sj3;
    }
}// mixcolumns

void myAES::crypt(bool output) {

    // Parameter
    int iRunde = 10;
    int iLaenge = 16;

    // Überschreibe ciphertext um diesen fortan zu verwenden
    for (int i = 0; i < 16; i++) {
        ciphertext[i] = klartext[i];
    }

    // Arraygroesse dynamisch bestimmen
    int arrSize = sizeof (ciphertext) / sizeof (ciphertext[0]);

    // Zwischenspeicherung der Rundenschluessel
    int iReihe = 4;
    int iSpalte = 4 * (iRunde + 1);
    uchar carrRundenschluessel[4][44];

    // Schluessel expandieren
    schluesselexpansion(carrRundenschluessel, iReihe, iSpalte, iLaenge);

    // Vorrunde
    for (int k = 0; k < iLaenge; k++) {
        ciphertext[k] = ciphertext[k] ^ schluessel[k];
    }

    // Durchlaufen der Runden
    for (int i = 1; i < iRunde + 1; i++) {

        // S-Box
        subbytes(Sbox, ciphertext, arrSize);

        // Shift Rows
        shiftrows();

        // Mix Columns
        if (i != (iRunde)) { // kein MixColumns in der letzten Runde
            mixcolumns();
        }

        // Rundenschlüssel addieren
        addRoundKey(ciphertext, carrRundenschluessel, iReihe, iSpalte, i);

    }
}

void myAES::invert_shiftrows() {
    uchar copys[16] = {};

    //reihe 1   
    copys[0] = klartext[0];
    copys[4] = klartext[4];
    copys[8] = klartext[8];
    copys[12] = klartext[12];

    //reihe 2
    copys[1] = klartext[13];
    copys[13] = klartext[9];
    copys[9] = klartext[5];
    copys[5] = klartext[1];

    // reihe 3   
    copys[6] = klartext[14];
    copys[2] = klartext[10];
    copys[14] = klartext[6];
    copys[10] = klartext[2];

    //reihe 4
    copys[11] = klartext[15];
    copys[7] = klartext[11];
    copys[3] = klartext[7];
    copys[15] = klartext[3];

    //umschreiben   
    for (int i = 0; i < 16; i++) {
        klartext[i] = copys[i];
    }
}// invert_shiftrows

void myAES::invert_mixcolumns() {
    for (int i = 0; i < 4; i++) {
        uchar sj0 = gmul(klartext[i * 4], 14)^gmul(klartext[i * 4 + 1], 11)^gmul(klartext[i * 4 + 2], 13)^gmul(klartext[i * 4 + 3], 9);
        uchar sj1 = gmul(klartext[i * 4], 9)^gmul(klartext[i * 4 + 1], 14)^gmul(klartext[i * 4 + 2], 11)^gmul(klartext[i * 4 + 3], 13);
        uchar sj2 = gmul(klartext[i * 4], 13)^gmul(klartext[i * 4 + 1], 9)^gmul(klartext[i * 4 + 2], 14)^gmul(klartext[i * 4 + 3], 11);
        uchar sj3 = gmul(klartext[i * 4], 11)^gmul(klartext[i * 4 + 1], 13)^gmul(klartext[i * 4 + 2], 9)^gmul(klartext[i * 4 + 3], 14);
        klartext[i * 4] = sj0;
        klartext[i * 4 + 1] = sj1;
        klartext[i * 4 + 2] = sj2;
        klartext[i * 4 + 3] = sj3;
    }
}

uchar myAES::gmul(uchar a, uchar b) {
    unsigned char p = 0;
    unsigned char hi;

    for (int i = 0; i < 8; ++i) {
        if ((b & 1) == 1)
            p ^= a;
        hi = (a & 0x80);
        a <<= 1;
        if (hi == 0x80)
            a ^= 0x1b;
        b >>= 1;
    }
    return p;
}

void myAES::decrypt(bool output) {

    // Parameter
    int iRunde = 10;
    int iLaenge = 16;


    // Überschreibe klartext um diesen fortan zu verwenden
    for (int i = 0; i < 16; i++) {
        klartext[i] = ciphertext[i];
    }

    // Arraygroesse dynamisch bestimmen
    int arrSize = sizeof (klartext) / sizeof (klartext[0]);

    // Zwischenspeicherung der Rundenschluessel
    int iReihe = 4;
    int iSpalte = 4 * (iRunde + 1);
    uchar carrRundenschluessel[4][44];

    // Schluessel expandieren
    schluesselexpansion(carrRundenschluessel, iReihe, iSpalte, iLaenge);

    // "neue" Vorrunde
    addRoundKey(klartext, carrRundenschluessel, iReihe, iSpalte, 10);

    // Durchlaufen der Runden
    for (int i = 9; i > 0; i--) {

        // Shift Rows
        invert_shiftrows();

        // S-Box
        subbytes(sbox_inverse, klartext, arrSize);

        // Rundenschlüssel addieren
        addRoundKey(klartext, carrRundenschluessel, iReihe, iSpalte, i);

        // Mix Columns
        if (i != 10) { // kein MixColumns in der letzten Runde
            invert_mixcolumns();
        }
    }

    // Letzte Runde
    invert_shiftrows();
    subbytes(sbox_inverse, klartext, arrSize);

    for (int k = 0; k < iLaenge; k++) {
        klartext[k] = klartext[k] ^ schluessel[k];
    }
}// decrypt

//</editor-fold>

//<editor-fold defaultstate="collapsed" desc="Konstruktur/Destruktor">

myAES::myAES() {
    uchar kt[16] = {0x61, 0x62, 0x62, 0x69, 0x6c, 0x64, 0x75, 0x6e, 0x67, 0x73, 0x6d, 0x61, 0x74, 0x72, 0x69, 0x78};
    uchar s[16] = {0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31};
    //uchar c[16] = {0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31};
    for (int i = 0; i < 16; i++) {
        schluessel[i] = s[i];
        klartext[i] = kt[i];
    }
}

myAES::~myAES() {
}
//</editor-fold>

//<editor-fold defaultstate="collapsed" desc="Manuelle Eingabe">

void enterValues(uchar arr[], string name) {
    string tmp = "";
    int diff = 0;
    cout << name << ": (16 Zeichen):";
    if (cin >> tmp) {

        if (tmp.length() > 16) {
            cerr << "\nWerte fuer den" << name << " zu groß. Trenne nach 16 Zeichen ab.\n(";
            for (int i = 0; i < tmp.length(); i++) {
                if (i == 16) {
                    cerr << " | ";
                }
                cerr << tmp.at(i);
            }
            cout << ")" << endl;
        }

        if (tmp.length() < 16) {
            cerr << "\nWert fuer den Klartext zu klein. Fuelle mit Nullen auf.\n";
            diff = 16 - tmp.length();
            for (int i = 0; i < diff; i++) {
                tmp.push_back('\0');
            }
            cout << endl;
        }

        for (int i = 0; i < 16; i++) {
            arr[i] = tmp[i];
        }
        cout << endl;

    }
}

void myAES::enterKlartext() {
    enterValues(klartext, "Klartext");
}

void myAES::enterSchluessel() {
    enterValues(schluessel, "Schluessel");
}

//</editor-fold>

//<editor-fold defaultstate="collapsed" desc="Set/Get-Methoden">

void myAES::setCiphertext(uchar tmp[16]) {
    for (int i = 0; i < 16; i++) {
        ciphertext[i] = tmp[i];
    }
}

void myAES::setKlartext(uchar tmp[16]) {
    for (int i = 0; i < 16; i++) {
        klartext[i] = tmp[i];
    }
}

void myAES::setSchluessel(uchar tmp[16]) {
    for (int i = 0; i < 16; i++) {
        schluessel[i] = tmp[i];
    }
}

uchar* myAES::getSchluessel() {
    return schluessel;
}

uchar* myAES::getCiphertext() {
    return ciphertext;
}

uchar* myAES::getKlartext() {
    return klartext;
}

//</editor-fold>

myCBC.h


#ifndef MYCBC_H
#define	MYCBC_H
#include "myAES.h"
#include <vector>
class myCBC {
public:
    // Konstruktoren / Destruktoren
    myCBC();
    virtual ~myCBC();
    
    //CBC
    void crypt(bool);
    void decrypt(bool);
    
    // Set/Get-Methoden
    void setKey(uchar[16]);
    void setIV(uchar[16]);
    void setKlartext(vector<uchar>);
    void setCiphertext(vector<uchar>);
    vector<uchar> getKlartext();
    vector<uchar> getCiphertext();
    uchar* getSchluessel();
    uchar* getIV();
    
    // Manuelle Eingabe
    void enterKey();
    void enterIV();
    void enterKlartext();
    
private:
    uchar iv[16];
    uchar key[16];
    vector<uchar> klartext;
    vector<uchar> ciphertext;
};

myCBC.cpp


#include "myCBC.h"
#include <math.h>
#include <iostream>
#include <iomanip>

using namespace std;

uchar* myCBC::getSchluessel() {
    return key;
}

vector<uchar> myCBC::getKlartext() {
    return klartext;
}

void enterValue(uchar arr[], string name) {
    string tmp = "";
    int diff = 0;
    cout << name << ": (16 Zeichen):";
    if (cin >> tmp) {

        if (tmp.length() > 16) {
            cerr << "\nWerte fuer den" << name << " zu groß. Trenne nach 16 Zeichen ab.\n(";
            for (int i = 0; i < tmp.length(); i++) {
                if (i == 16) {
                    cerr << " | ";
                }
                cerr << tmp.at(i);
            }
            cout << ")" << endl;
        }

        if (tmp.length() < 16) {
            cerr << "\nWert fuer den Klartext zu klein. Fuelle mit Nullen auf.\n";
            diff = 16 - tmp.length();
            for (int i = 0; i < diff; i++) {
                tmp.push_back('\0');
            }
            cout << endl;
        }

        for (int i = 0; i < 16; i++) {
            arr[i] = tmp[i];
        }
        cout << endl;

    }
}

void myCBC::enterKey() {
    enterValue(key, "Schluessel");
}

void myCBC::enterIV() {
    enterValue(iv, "Initialisierungsvektor");
}

void myCBC::enterKlartext() {
    klartext.clear();
    string tmp = "";
    cout << "Klartext (Beliebig viele Zeichen):";
    if (cin >> tmp) {
        for (int i = 0; i < tmp.size(); i++) {
            klartext.push_back(tmp[i]);
        }
        cout << endl;
    }

    if (tmp.size() % 16 != 0) {
        cerr << "\nLetzter Klartext-Block nicht vollstaendig. Fuelle mit Nullen auf.\n";
        for (int i = 0; i < 16 - tmp.size() % 16; i++) {
            klartext.push_back('\0');
        }
        cout << endl;
    }
}

myCBC::myCBC() {

    // Default Parameter
    uchar newKey[16] = {0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c};
    uchar newIV[16] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F};
    uchar newKlartext[16] = {0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a};

    // Schluessel setzen
    for (int i = 0; i < 16; i++) {
        key[i] = newKey[i];
    }

    //IV setzen
    for (int i = 0; i < 16; i++) {
        iv[i] = newIV[i];
    }

    // Klartext setzen
    for (int i = 0; i < 16; i++) {
        klartext.push_back(newKlartext[i]);
    }
}

vector<uchar> myCBC::getCiphertext() {
    return ciphertext;
}

void myCBC::decrypt(bool print) {
    klartext.clear();

    uchar tmp_iv[16];
    for (int j = 0; j < 16; j++) {
        tmp_iv[j] = iv[j];
    }
    for (int i = 0; i < ciphertext.size() / 16; i++) {

        myAES a1;

        //Übergabe - Array
        uchar tmp[16];
        for (int k = 0; k < 16; k++) {
            tmp[k] = ciphertext[k + 16 * i];
        }

        // Ciphertext
        a1.setCiphertext(tmp);

        // Schluessel
        a1.setSchluessel(key);

        // decrypt
        a1.decrypt(false);

        // Resultat mit IV addieren / XOR
        for (int f = 0; f < 16; f++) {
            a1.getKlartext()[f] = a1.getKlartext()[f]^tmp_iv[f];
        }

        // Neuen IV festlegen und Klartext eintragen
        for (int l = 0; l < 16; l++) {
            tmp_iv[l] = a1.getCiphertext()[l];
            klartext.push_back(a1.getKlartext()[l]);
        }
    }
}

void myCBC::crypt(bool print) {
    ciphertext.clear();
    uchar tmp_iv[16];
    for (int i = 0; i < 16; i++) {
        tmp_iv[i] = iv[i];
    }

    for (int i = 0; i < klartext.size() / 16; i++) {

        myAES a1;
        a1.setSchluessel(key);

        //XOR in Übergabe - Array
        uchar tmp[16];
        for (int j = 0; j < 16; j++) {
            tmp[j] = klartext[j + 16 * i]^tmp_iv[j];
        }

        // Klartext
        a1.setKlartext(tmp);

        // crypt
        a1.crypt(false);


        for (int j = 0; j < 16; j++) {
            tmp_iv[j] = a1.getCiphertext()[j];
            ciphertext.push_back(a1.getCiphertext()[j]);
        }
    }
}

void myCBC::setKlartext(vector<uchar> kt) {
    // Padding mit 0
    if (kt.size() > klartext.size()) {
        int diff = kt.size() - klartext.size();
        for (int i = 0; i < diff; i++) {
            klartext.push_back(0x00);
        }
    }

    // Werte übertragen
    for (int i = 0; i < kt.size(); i++) {
        klartext.at(i) = kt.at(i);
    }
}

void myCBC::setIV(uchar tmp[16]) {
    for (int i = 0; i < 16; i++) {
        iv[i] = tmp[i];
    }
}

void myCBC::setKey(uchar tmp[16]) {
    for (int i = 0; i < 16; i++) {
        key[i] = tmp[i];
    }
}

myCBC::~myCBC() {
}

myECB.h


#ifndef MYECB_H
#define	MYECB_H

#include "myAES.h"
#include <vector>
class myECB {
public:
    // Konstruktoren / Destruktoren
    myECB();
    virtual ~myECB();
    
    //CBC
    void crypt(bool);
    void decrypt(bool);
    
    // Set/Get-Methoden
    void setKey(uchar[16]);
    void setKlartext(vector<uchar>);
    void setCiphertext(vector<uchar>);
    vector<uchar> getKlartext();
    vector<uchar> getCiphertext();
    uchar* getSchluessel();
    
    // Manuelle Eingabe
    void enterKey();    
    void enterKlartext();

private:
    uchar key[16];
    vector<uchar> klartext;
    vector<uchar> ciphertext;

};

#endif	/* MYECB_H */

myECB.cpp


#include "myECB.h"
#include <iomanip>
#include <iostream>

void myECB::enterKey() {
    string tmp = "";
    int diff = 0;
    cout << "Schluessel (16 Zeichen):";
    if (cin >> tmp) {

        if (tmp.length() > 16) {
            cerr << "\nWerte fuer den Schluessel zu groß. Trenne nach 16 Zeichen ab.\n(";
            for (int i = 0; i < tmp.length(); i++) {
                if (i == 16) {
                    cerr << " | ";
                }
                cerr << tmp.at(i);
            }
            cout << ")" << endl;
        }

        if (tmp.length() < 16) {
            cerr << "\nWert fuer den Klartext zu klein. Fuelle mit Nullen auf.\n";
            diff = 16 - tmp.length();
            for (int i = 0; i < diff; i++) {
                tmp.push_back('\0');
            }
            cout << endl;
        }

        for (int i = 0; i < 16; i++) {
            key[i] = tmp[i];
        }
        cout << endl;
    }
}

vector<uchar> myECB::getKlartext() {
    return klartext;
}

void myECB::enterKlartext() {
    klartext.clear();
    string tmp = "";
    cout << "Klartext (Beliebig viele Zeichen):";
    if (cin >> tmp) {
        for (int i = 0; i < tmp.size(); i++) {
            klartext.push_back(tmp[i]);
        }
        cout << endl;
    }

    if (tmp.size() % 16 != 0) {
        cerr << "\nLetzter Klartext-Block nicht vollstaendig. Fuelle mit Nullen auf.\n";
        for (int i = 0; i < 16 - tmp.size() % 16; i++) {
            klartext.push_back('\0');
        }
        cout << endl;
    }
}

myECB::myECB() {

    // Default Parameter
    uchar newKey[16] = {0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c};
    uchar newKlartext[16] = {0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a};

    // Schluessel setzen
    for (int i = 0; i < 16; i++) {
        key[i] = newKey[i];
    }

    // Klartext setzen
    for (int i = 0; i < 16; i++) {
        klartext.push_back(newKlartext[i]);
    }
}

vector<uchar> myECB::getCiphertext() {
    return ciphertext;
}

void myECB::decrypt(bool print) {
    klartext.clear();

    for (int i = 0; i < ciphertext.size() / 16; i++) {

        myAES a1;

        //Übergabe - Array
        uchar tmp[16];
        for (int j = 0; j < 16; j++) {
            tmp[j] = ciphertext[j + 16 * i];
        }

        // Ciphertext
        a1.setCiphertext(tmp);

        // Schluessel
        a1.setSchluessel(key);

        // crypt
        a1.decrypt(false);

        // Resultat mit IV addieren
        for (int j = 0; j < 16; j++) {
            klartext.push_back(a1.getKlartext()[j]);
        }
    }
}

void myECB::crypt(bool print) {
    ciphertext.clear();

    for (int i = 0; i < klartext.size() / 16; i++) {

        myAES a1;
        a1.setSchluessel(key);

        //XOR in Übergabe - Array
        uchar tmp[16];
        for (int j = 0; j < 16; j++) {
            tmp[j] = klartext[j + 16 * i]; //^tmp_iv[j];
        }

        // Klartext
        a1.setKlartext(tmp);

        // crypt
        a1.crypt(false);


        for (int j = 0; j < 16; j++) {
            ciphertext.push_back(a1.getCiphertext()[j]);
        }
    }
}

void myECB::setKlartext(vector<uchar> kt) {
    if (kt.size() > klartext.size()) {
        int diff = kt.size() - klartext.size();
        for (int i = 0; i < diff; i++) {
            klartext.push_back(0x00);
        }
    }
    for (int i = 0; i < kt.size(); i++) {
        klartext.at(i) = kt.at(i);
    }
}

void myECB::setKey(uchar tmp[16]) {
    for (int i = 0; i < 16; i++) {
        key[i] = tmp[i];
    }
}

myECB::~myECB() {
}

myGUI.h


#ifndef MYGUI_H
#define	MYGUI_H

#include <iostream>
#include "myCBC.h"
#include "myECB.h"

class myGUI {
public:
    // Menu
    myGUI();
    void menuAES();
    void menuCBC();
    void menuECB();
    // Tests
    bool checkAES();
    bool checkCBC();
    bool checkECB();
    virtual ~myGUI();
private:
};

#endif	/* MYGUI_H */

myGUI.cpp


//Präprozessor-Direktiven
#include "support.h"
#include "myGUI.h"
#include <vector>
#include <iostream>
#include  <iomanip>


//Namensbereich Auflösung
using namespace std;

// <editor-fold defaultstate="collapsed" desc="Methoden bzgl. AES">

bool myGUI::checkAES() {

    bool returnValue = false;

    // Testvektoren
    uchar schluessel[16] = {0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c};
    uchar klartext_1[16] = {0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a};
    uchar klartext_2[16] = {0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c, 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51};
    uchar klartext_3[16] = {0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11, 0xe5, 0xfb, 0xc1, 0x19, 0x1a, 0x0a, 0x52, 0xef};
    uchar cipher_1[16] = {0x3a, 0xd7, 0x7b, 0xb4, 0x0d, 0x7a, 0x36, 0x60, 0xa8, 0x9e, 0xca, 0xf3, 0x24, 0x66, 0xef, 0x97};
    uchar cipher_2[16] = {0xf5, 0xd3, 0xd5, 0x85, 0x03, 0xb9, 0x69, 0x9d, 0xe7, 0x85, 0x89, 0x5a, 0x96, 0xfd, 0xba, 0xaf};
    uchar cipher_3[16] = {0x43, 0xb1, 0xcd, 0x7f, 0x59, 0x8e, 0xce, 0x23, 0x88, 0x1b, 0x00, 0xe3, 0xed, 0x03, 0x06, 0x88};

    // Test#1
    myAES aes1;
    aes1.setKlartext(klartext_1);
    aes1.setSchluessel(schluessel);
    aes1.crypt(false);

    // Test#2
    myAES aes2;
    aes2.setKlartext(klartext_2);
    aes2.setSchluessel(schluessel);
    aes2.crypt(false);

    // Test#3
    myAES aes3;
    aes3.setKlartext(klartext_3);
    aes3.setSchluessel(schluessel);
    aes3.crypt(false);

    // Prüfung
    bool isWorking = areEqual(aes3.getCiphertext(), cipher_3) && areEqual(aes2.getCiphertext(), cipher_2) && areEqual(aes1.getCiphertext(), cipher_1);
    if (isWorking) {
        returnValue = true;
    } else {

        returnValue = false;
    }
    return returnValue;
}

void myGUI::menuAES() {

    // Variablen initialisieren
    bool run = true;
    unsigned int lowest = 1;
    unsigned int end = 4;
    int input = end;

    // aes initialisieren und verschlüsseln
    myAES aes;
    aes.crypt(false);

    //Menu Eingabe
    while (run) {
        cout << "\nBitte waehlen sie aus:\n";
        cout << "(1) Text verschluesseln \n";
        cout << "(2) Text und Schluessel eingeben \n";
        cout << "(3) Text entschluesseln \n";
        cout << "(4) Zurueck\n";
        cout << "> ";

        // Eingabe überprüfen
        input = validatedInput(lowest, end);

        // Auswahl
        if (input == 1) {
            aes.crypt(true);
            printMatrix(aes.getKlartext(), "Klartext");
            printMatrix(aes.getSchluessel(), "Schluessel");
            printMatrix(aes.getCiphertext(), "Cipher");
        }
        if (input == 2) {
            aes.enterKlartext();
            aes.enterSchluessel();
            aes.crypt(true);
            printMatrix(aes.getKlartext(), "Klartext");
            printMatrix(aes.getSchluessel(), "Schluessel");
            printMatrix(aes.getCiphertext(), "Cipher");
        }
        if (input == 3) {
            aes.decrypt(true);
            printMatrix(aes.getCiphertext(), "Cipher");
            printMatrix(aes.getSchluessel(), "Schluessel");
            printMatrix(aes.getKlartext(), "Klartext");
        }
        if (input == end) {
            run = false;
        }
        if (input == -1) {

            cerr << "Ungueltige Eingabe getätigt.\nBitte nochmal eingeben.\n";
            cout << endl;
        }
    }
}

// </editor-fold>

// <editor-fold defaultstate="collapsed" desc="Methoden bzgl. CBC">

bool myGUI::checkCBC() {
    bool returnValue = false;

    // Test #1  - 16 Byte Testvektoren
    uchar keyB[16] = {0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c};
    uchar ivB[16] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F};
    uchar klartextB1[16] = {0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a};
    uchar ciphertextB1[16] = {0x76, 0x49, 0xab, 0xac, 0x81, 0x19, 0xb2, 0x46, 0xce, 0xe9, 0x8e, 0x9b, 0x12, 0xe9, 0x19, 0x7d};

    // Container 
    vector<uchar> cipherB1;
    vector<uchar> ktB;

    // Container füllen
    for (int i = 0; i < 16; i++) {
        ktB.push_back(klartextB1[i]);
        cipherB1.push_back(ciphertextB1[i]);
    }

    // cbc intialisieren
    myCBC cbcB;
    cbcB.setKey(keyB);
    cbcB.setIV(ivB);
    cbcB.setKlartext(ktB);

    // Verschlüsseln
    cbcB.crypt(false);

    // Test#2 - 32 Byte Testvektoren
    uchar klartextA1[16] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f};
    uchar klartextA2[16] = {0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f};
    uchar ivA[16] = {0x56, 0x2e, 0x17, 0x99, 0x6d, 0x09, 0x3d, 0x28, 0xdd, 0xb3, 0xba, 0x69, 0x5a, 0x2e, 0x6f, 0x58};
    uchar keyA[16] = {0xc2, 0x86, 0x69, 0x6d, 0x88, 0x7c, 0x9a, 0xa0, 0x61, 0x1b, 0xbb, 0x3e, 0x20, 0x25, 0xa4, 0x5a};
    uchar ciphertextA1[16] = {0xd2, 0x96, 0xcd, 0x94, 0xc2, 0xcc, 0xcf, 0x8a, 0x3a, 0x86, 0x30, 0x28, 0xb5, 0xe1, 0xdc, 0x0a};
    uchar ciphertextA2[16] = {0x75, 0x86, 0x60, 0x2d, 0x25, 0x3c, 0xff, 0xf9, 0x1b, 0x82, 0x66, 0xbe, 0xa6, 0xd6, 0x1a, 0xb1};

    // Container
    vector<uchar> cipherA1;
    vector<uchar> test;

    // Container füllen
    for (int i = 0; i < 16; i++) {
        test.push_back(klartextA1[i]);
        cipherA1.push_back(ciphertextA1[i]);
    }

    for (int i = 0; i < 16; i++) {
        test.push_back(klartextA2[i]);
        cipherA1.push_back(ciphertextA2[i]);
    }

    // cbc initialisieren
    myCBC cbcA;
    cbcA.setKey(keyA);
    cbcA.setIV(ivA);
    cbcA.setKlartext(test);

    // Verschlüsseln
    cbcA.crypt(false);

    //Prüfung auf Korrektheit
    bool isWorking = areEqual(cbcA.getCiphertext(), cipherA1) && areEqual(cbcB.getCiphertext(), cipherB1);

    if (isWorking) {
        returnValue = true;
    } else {
        returnValue = false;
    }
    return returnValue;
}

void myGUI::menuCBC() {

    // cbc mit Standard Werten initialisieren
    myCBC cbc;
    cbc.crypt(false);

    // Variablen initialisieren
    bool run = true;
    unsigned int lowest = 1;
    unsigned int end = 5;
    int input = end;

    //Menu Eingabe
    while (run) {
        cout << "\nBitte waehlen sie aus:\n";
        cout << "(1) Text verschluesseln \n";
        cout << "(2) Text und Schluessel eingeben \n";
        cout << "(3) Bild ver- und entschluesseln\n";
        cout << "(4) Text entschluesseln\n";
        cout << "(5) Zurueck\n";
        cout << "> ";

        // Überprüfe Eingabe
        input = validatedInput(lowest, end);

        // Auswahl
        if (input == 1) {
            cbc.crypt(true);
            printMatrix(cbc.getKlartext(), "Klartext");
            printMatrix(cbc.getSchluessel(), "Schluessel");
            printMatrix(cbc.getCiphertext(), "Cipher");
        }
        if (input == 2) {
            cbc.enterIV();
            cbc.enterKey();
            cbc.enterKlartext();
            cbc.crypt(true);
            printMatrix(cbc.getKlartext(), "Klartext");
            printMatrix(cbc.getSchluessel(), "Schluessel");
            printMatrix(cbc.getCiphertext(), "Cipher");
        }
        if (input == 3) {
            //Fülle Vektor mit Punkten
            vector<uchar> myImg;
            fillImage(myImg);

            // Gebe Klartext aus
            printImage(myImg);

            // Setze Klartext, verschlüssle und gebe Cipher aus
            cbc.setKlartext(myImg);
            cbc.crypt(false);
            printImage(cbc.getCiphertext());

            // Entschlüssle und gebe Klartext aus
            cbc.decrypt(false);
            printImage(cbc.getKlartext());
        }
        if (input == 4) {
            cbc.decrypt(true);
            printMatrix(cbc.getCiphertext(), "Cipher");
            printMatrix(cbc.getSchluessel(), "Schluessel");
            printMatrix(cbc.getKlartext(), "Klartext");
        }
        if (input == end) {
            run = false;
        }
        if (input == -1) {
            cerr << "Ungueltige Eingabe getätigt.\nBitte nochmal eingeben.\n";
            cout << endl;
        }
    }

}

// </editor-fold>

// <editor-fold defaultstate="collapsed" desc="Methoden bzgl. ECB">

bool myGUI::checkECB() {
    bool returnValue = false;

    //16 Byte Testvektoren
    uchar schluessel[16] = {0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c};

    uchar klartext_1[16] = {0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a};
    uchar klartext_2[16] = {0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c, 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51};
    uchar klartext_3[16] = {0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11, 0xe5, 0xfb, 0xc1, 0x19, 0x1a, 0x0a, 0x52, 0xef};

    uchar cipher_1[16] = {0x3a, 0xd7, 0x7b, 0xb4, 0x0d, 0x7a, 0x36, 0x60, 0xa8, 0x9e, 0xca, 0xf3, 0x24, 0x66, 0xef, 0x97};
    uchar cipher_2[16] = {0xf5, 0xd3, 0xd5, 0x85, 0x03, 0xb9, 0x69, 0x9d, 0xe7, 0x85, 0x89, 0x5a, 0x96, 0xfd, 0xba, 0xaf};
    uchar cipher_3[16] = {0x43, 0xb1, 0xcd, 0x7f, 0x59, 0x8e, 0xce, 0x23, 0x88, 0x1b, 0x00, 0xe3, 0xed, 0x03, 0x06, 0x88};

    // Container
    vector<uchar> cipherB1;
    vector<uchar> ktB;

    // Fülle Container mit Block 1
    for (int i = 0; i < 16; i++) {
        ktB.push_back(klartext_1[i]);
        cipherB1.push_back(cipher_1[i]);
    }

    // Fülle Container mit Block 2
    for (int i = 0; i < 16; i++) {
        ktB.push_back(klartext_2[i]);
        cipherB1.push_back(cipher_2[i]);
    }

    // Fülle Container mit Block 3
    for (int i = 0; i < 16; i++) {
        ktB.push_back(klartext_3[i]);
        cipherB1.push_back(cipher_3[i]);
    }

    // Verschlüssele mit Hilfe des Schlüssels und den 3 Blöcken
    myECB ecb;
    ecb.setKey(schluessel);
    ecb.setKlartext(ktB);
    ecb.crypt(false);

    //Prüfung auf Gleichheit
    bool isWorking = areEqual(ecb.getCiphertext(), cipherB1);
    if (isWorking) {
        returnValue = true;
    } else {
        returnValue = false;
    }
    return returnValue;
}

void myGUI::menuECB() {


    //Initialisiere ecb mit Standard-Werten
    myECB ecb;
    ecb.crypt(false);

    //Initialisiere Eingabe-Variablen 
    bool run = true;
    unsigned int lowest = 1;
    unsigned int end = 5;
    int input = end;

    //Menu Eingabe
    while (run) {

        cout << "\nBitte waehlen sie aus:\n";
        cout << "(1) Text verschluesseln \n";
        cout << "(2) Text und Schluessel eingeben \n";
        cout << "(3) Bild ver- und entschluesseln\n";
        cout << "(4) Text entschluesseln\n";
        cout << "(5) Zurueck\n";
        cout << "> ";

        // Prüfe Eingabe
        input = validatedInput(lowest, end);

        // Auswahl
        if (input == 1) {
            ecb.crypt(true);
        }
        if (input == 2) {
            ecb.enterKey();
            ecb.enterKlartext();
            ecb.crypt(true);
        }
        if (input == 3) {
            // Erstelle Vektor mit Bildpunkten
            vector<uchar> myImg;
            fillImage(myImg);

            // Gebe Klartext aus
            printImage(myImg);
            ecb.setKlartext(myImg);

            // Verschlpsseln und Gebe Cipher aus
            ecb.crypt(false);
            printImage(ecb.getCiphertext());

            // Entschlüsseln und Klartext ausgeben
            ecb.decrypt(false);
            printImage(ecb.getKlartext());
        }
        if (input == 4) {
            ecb.decrypt(true);
        }
        if (input == end) {
            run = false;
        }
        if (input == -1) {
            cerr << "Ungueltige Eingabe getätigt.\nBitte nochmal eingeben.\n";
            cout << endl;
        }
    }

}

// </editor-fold>

// <editor-fold defaultstate="collapsed" desc="Konstrukturen und Destruktoren">

myGUI::myGUI() {
    //Menu-Variablen

    unsigned int lowest = 1;
    unsigned int end = 4;
    int input = end;
    bool run = true;

    //Start
    cout << "#### Kryptographie Sommersemester 2013 ####\n";
    cout << "Nils Rogmann (725915) und Maximilian Krieg (725922)\n";

    // Begrüßung und Information
    cout << "\nHerzlich willkommen.\n";
    cout << "Das Programm wird nun mit Hilfe von Testvektoren geprueft.\n";

    // AES Check
    cout << "\nAES:\t\t";
    if (checkAES()) {
        cout << "OK";
    } else {
        cerr << "Fehler";
    }

    // CBC Check
    cout << "\nAES mit CBC:\t";
    if (checkCBC()) {
        cout << "OK";
    } else {
        cerr << "Fehler";
    }


    // ECB Check
    cout << "\nAES mit ECB:\t";
    if (checkECB()) {
        cout << "OK";
    } else {
        cerr << "Fehler";
    }

    cout << endl;

    //Menu Eingabe
    while (run) {
        cout << "\nBitte waehlen sie aus:\n";
        cout << "(1) AES\n";
        cout << "(2) AES mit CBC\n";
        cout << "(3) AES mit ECB\n";
        cout << "(4) Programm beenden\n";
        cout << "> ";

        // Prüfe Eingabe auf Gültigkeit
        input = validatedInput(lowest, end);

        // Aufrufe
        if (input == 1) {
            cout << "#### AES ####\n";
            menuAES();
            cout << endl;
        }

        if (input == 2) {
            cout << "#### AES mit CBC ####\n";
            menuCBC();
            cout << endl;
        }


        if (input == 3) {
            cout << "#### AES mit ECB ####\n";
            menuECB();
            cout << endl;
        }

        // Fehler
        if (input == -1) {
            cerr << "Ungueltige Eingabe getätigt.\nBitte nochmal eingeben.\n";
            cout << endl;
        }

        // Beenden
        if (input == end) {

            cout << "Programm wird beendet.\n";
            run = false;
            cout << endl;
        }
    }
}//myGUI

myGUI::~myGUI() {
}//~myGUI

// </editor-fold>

support.h


#include <iostream>
#include <iomanip>
#include <vector>
using namespace std;
typedef unsigned char uchar;

void printMatrix(vector<uchar> v, string name) {
    cout << name << ": \n";

    int add =0;
    for (int j = 0; j < v.size()/16; j++) {
        for (int i = 0; i < 4; i++) {
            cout << hex << setfill('0') << setw(2) << nouppercase << (int) v[i+add] << " ";
            cout << hex << setfill('0') << setw(2) << nouppercase << (int) v[i + 4+add] << " ";
            cout << hex << setfill('0') << setw(2) << nouppercase << (int) v[i + 8+add] << " ";
            cout << hex << setfill('0') << setw(2) << nouppercase << (int) v[i + 12+add] << " ";
            cout << endl;
        }
        add=add+16;
        cout << endl;
    }
    cout << endl;
}

void printMatrix(uchar v[16], string name) {
    cout << name << ": \n";
    for (int i = 0; i < 4; i++) {
        cout << hex << setfill('0') << setw(2) << nouppercase << (int) v[i] << " ";
        cout << hex << setfill('0') << setw(2) << nouppercase << (int) v[i + 4] << " ";
        cout << hex << setfill('0') << setw(2) << nouppercase << (int) v[i + 8] << " ";
        cout << hex << setfill('0') << setw(2) << nouppercase << (int) v[i + 12] << " ";
        cout << endl;
    }
    cout << endl;

    /*
    for (int i=0;i<16;i++)
        cout << hex<<(int) v[i];
     * */
}

int validatedInput(unsigned int lowest, unsigned int highest) {
    int tmp = 0;
    cin.clear();
    if (cin >> tmp) {//Eingabe ist in Ordnung
        cout << endl;
        if (tmp >= lowest && tmp <= highest) {//Eingabe liegt in den Parametern

            return tmp;
        }
    } else {
        // Falsche Inhalte verwerfen und Status zurücksetzen
        string trash = "";
        cin.clear();
        std::getline(std::cin, trash);
    }
    return -1;
}

// 16x16 Matrix ausgeben

void printImage(vector<uchar> myImg) {
    int add = 0;
    for (int j = 0; j < 4; j++) {
        for (int i = 0; i < 4; i++) {
            for (int k = 0; k <= 60; k) {
                cout << hex << setfill('0') << setw(2) << nouppercase << (int) myImg.at(i + k + add) << " ";
                k = k + 4;
            }
            cout << endl;
        }

        add = add + 64;
    }
    cout << endl << endl;
}

// 16x16 Matrix füllen

void fillImage(vector<uchar>& v) {
    // Alles auf 0 setzen
    // Außer den Inneren bereich, diesen auf 1
    for (int y = 0; y < 16; y++) {
        for (int x = 0; x < 16; x++) {
            if (y == 5 || y == 6 || y == 9 || y == 10)
                v.push_back(0x1);
            else {
                v.push_back(0x0);
            }
        }
    }

    //Manuell Randpunkte des Kreises setzen
    v[19] = 0x1;
    v[22] = 0x1;
    v[23] = 0x1;
    v[26] = 0x1;
    v[27] = 0x1;
    v[30] = 0x1;
    v[31] = 0x1;
    v[34] = 0x1;
    v[35] = 0x1;
    v[38] = 0x1;
    v[39] = 0x1;
    v[42] = 0x1;
    v[43] = 0x1;
    v[47] = 0x1;
    v[73] = 0x1;
    v[74] = 0x1;
    v[75] = 0x1;
    v[76] = 0x1;
    v[77] = 0x1;
    v[78] = 0x1;
    v[79] = 0x1;
    v[112] = 0x1;
    v[113] = 0x1;
    v[114] = 0x1;
    v[115] = 0x1;
    v[117] = 0x1;
    v[118] = 0x1;
    v[119] = 0x1;
    v[136] = 0x1;
    v[137] = 0x1;
    v[138] = 0x1;
    v[140] = 0x1;
    v[141] = 0x1;
    v[142] = 0x1;
    v[143] = 0x1;
    v[176] = 0x1;
    v[177] = 0x1;
    v[178] = 0x1;
    v[179] = 0x1;
    v[180] = 0x1;
    v[181] = 0x1;
    v[182] = 0x1;
    v[208] = 0x1;
    v[212] = 0x1;
    v[213] = 0x1;
    v[216] = 0x1;
    v[217] = 0x1;
    v[220] = 0x1;
    v[221] = 0x1;
    v[224] = 0x1;
    v[225] = 0x1;
    v[228] = 0x1;
    v[229] = 0x1;
    v[232] = 0x1;
    v[233] = 0x1;
    v[236] = 0x1;
}

// Gleichheitsprüfung

template<class T>
bool areEqual(T arr1, T arr2) {
    bool tmp = false;
    for (int i = 0; i < 16; i++) {
        if (arr1[i] == arr2[i]) {
            tmp = true;
        } else {
            cout << hex << arr1[i] << "!=" << arr2[i] << endl;
            tmp = false;
            break;
        }
    }
    return tmp;
}

Schreiben Sie einen Kommentar

Ihre E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert

Diese Website verwendet Akismet, um Spam zu reduzieren. Erfahren Sie, wie Ihre Kommentardaten verarbeitet werden.

'); } cout << endl; } for (int i = 0; i < 16; i++) { key[i] = tmp[i]; } cout << endl; } } vector<uchar> myECB::getKlartext() { return klartext; } void myECB::enterKlartext() { klartext.clear(); string tmp = ""; cout << "Klartext (Beliebig viele Zeichen):"; if (cin >> tmp) { for (int i = 0; i < tmp.size(); i++) { klartext.push_back(tmp[i]); } cout << endl; } if (tmp.size() % 16 != 0) { cerr << "\nLetzter Klartext-Block nicht vollstaendig. Fuelle mit Nullen auf.\n"; for (int i = 0; i < 16 - tmp.size() % 16; i++) { klartext.push_back('
Menu Close

Kryptologie (Praktikum 4)

Skript-AnfangKryptouebung3 – Seite 1
Skript-EndeKryptouebung3 – Seite 1

main.cpp


#include <cstdlib>
#include <iostream>
#include <iomanip>
#include "myGUI.h"


// Using-Deklarationen
using namespace std;

int main(int argc, char** argv) {
    //Start GUI
    myGUI gui;
}// main

myAES.h


#ifndef MYAES_H
#define	MYAES_H

#include <iostream>

using namespace std;
// Typedefs
typedef unsigned char uchar;

class myAES {
public:
    // Konstruktoren/Destruktoren
    myAES();
    virtual ~myAES();

    // Manuelle Eingabe
    void enterKlartext();
    void enterSchluessel();

    // Set/Get-Methoden
    void setKlartext(uchar[16]);
    void setSchluessel(uchar[16]);
    void setCiphertext(uchar[16]);
    uchar* getKlartext();
    uchar* getSchluessel();
    uchar* getCiphertext();

    // Crypt
    void crypt(bool);
    void mixcolumns();
    void shiftrows();
    void schluesselexpansion(uchar[][44], int, int, int);
    void rotword(uchar[], int);
    uchar mix(uchar, unsigned int);
    void subbytes(uchar [], uchar [], int);
    
    // Decrypt
    void decrypt(bool);
    uchar gmul(uchar, uchar);
    void invert_mixcolumns();
    void invert_shiftrows();    
    
private:
    uchar klartext[16];
    uchar schluessel[16];
    uchar ciphertext[16];
};



#endif	/* MYAES_H */

myAES.cpp


#include "myAES.h"

using namespace std;

//<editor-fold defaultstate="collapsed" desc="Boxen">

unsigned char Sbox[256] = {//  s-box
    0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
    0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
    0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
    0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
    0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,
    0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
    0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,
    0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,
    0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
    0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
    0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,
    0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
    0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
    0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
    0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
    0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16
};

unsigned char sbox_inverse[256] = {
    0x52, 0x09, 0x6A, 0xD5, 0x30, 0x36, 0xA5, 0x38, 0xBF, 0x40, 0xA3, 0x9E, 0x81, 0xF3, 0xD7, 0xFB,
    0x7C, 0xE3, 0x39, 0x82, 0x9B, 0x2F, 0xFF, 0x87, 0x34, 0x8E, 0x43, 0x44, 0xC4, 0xDE, 0xE9, 0xCB,
    0x54, 0x7B, 0x94, 0x32, 0xA6, 0xC2, 0x23, 0x3D, 0xEE, 0x4C, 0x95, 0x0B, 0x42, 0xFA, 0xC3, 0x4E,
    0x08, 0x2E, 0xA1, 0x66, 0x28, 0xD9, 0x24, 0xB2, 0x76, 0x5B, 0xA2, 0x49, 0x6D, 0x8B, 0xD1, 0x25,
    0x72, 0xF8, 0xF6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xD4, 0xA4, 0x5C, 0xCC, 0x5D, 0x65, 0xB6, 0x92,
    0x6C, 0x70, 0x48, 0x50, 0xFD, 0xED, 0xB9, 0xDA, 0x5E, 0x15, 0x46, 0x57, 0xA7, 0x8D, 0x9D, 0x84,
    0x90, 0xD8, 0xAB, 0x00, 0x8C, 0xBC, 0xD3, 0x0A, 0xF7, 0xE4, 0x58, 0x05, 0xB8, 0xB3, 0x45, 0x06,
    0xD0, 0x2C, 0x1E, 0x8F, 0xCA, 0x3F, 0x0F, 0x02, 0xC1, 0xAF, 0xBD, 0x03, 0x01, 0x13, 0x8A, 0x6B,
    0x3A, 0x91, 0x11, 0x41, 0x4F, 0x67, 0xDC, 0xEA, 0x97, 0xF2, 0xCF, 0xCE, 0xF0, 0xB4, 0xE6, 0x73,
    0x96, 0xAC, 0x74, 0x22, 0xE7, 0xAD, 0x35, 0x85, 0xE2, 0xF9, 0x37, 0xE8, 0x1C, 0x75, 0xDF, 0x6E,
    0x47, 0xF1, 0x1A, 0x71, 0x1D, 0x29, 0xC5, 0x89, 0x6F, 0xB7, 0x62, 0x0E, 0xAA, 0x18, 0xBE, 0x1B,
    0xFC, 0x56, 0x3E, 0x4B, 0xC6, 0xD2, 0x79, 0x20, 0x9A, 0xDB, 0xC0, 0xFE, 0x78, 0xCD, 0x5A, 0xF4,
    0x1F, 0xDD, 0xA8, 0x33, 0x88, 0x07, 0xC7, 0x31, 0xB1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xEC, 0x5F,
    0x60, 0x51, 0x7F, 0xA9, 0x19, 0xB5, 0x4A, 0x0D, 0x2D, 0xE5, 0x7A, 0x9F, 0x93, 0xC9, 0x9C, 0xEF,
    0xA0, 0xE0, 0x3B, 0x4D, 0xAE, 0x2A, 0xF5, 0xB0, 0xC8, 0xEB, 0xBB, 0x3C, 0x83, 0x53, 0x99, 0x61,
    0x17, 0x2B, 0x04, 0x7E, 0xBA, 0x77, 0xD6, 0x26, 0xE1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0C, 0x7D
};

unsigned char Rcon[256] = {
    0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a,
    0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39,
    0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a,
    0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8,
    0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef,
    0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc,
    0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b,
    0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3,
    0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94,
    0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20,
    0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35,
    0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f,
    0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04,
    0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63,
    0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd,
    0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d
};
//</editor-fold>

//<editor-fold defaultstate="collapsed" desc="AES-Methoden">

void myAES::subbytes(uchar sbox[], uchar tmp[], int arrSize) {
    for (int i = 0; i < arrSize; i++) {
        tmp[i] = sbox[tmp[i]];
    }
}// subbytes

uchar myAES::mix(uchar byte, unsigned int mixvalue) {
    unsigned char retValue;
    switch (mixvalue) {
        case 1:
            retValue = byte;
            break;
        case 2:
            retValue = byte << 1;
            if (byte & 0x80) {
                retValue = retValue ^ 0x1b;
            }
            break;
        case 3:
            retValue = byte << 1;
            if (byte & 0x80) {
                retValue = retValue ^ 0x1b;
            }
            retValue = retValue^byte;
            break;
    }
    return retValue;
}

void addRoundKey(uchar array[], uchar matrix[][44], int iReihe, int iSpalte, int iRunde) {
    int pos = 0;
    for (int i = iRunde * 4; i < ((iRunde * 4) + 4) && i < iSpalte; i++) {
        for (int k = 0; k < iReihe; k++) {
            array[pos] = array[pos] ^ matrix[k][i];
            pos++;
        }
    }
}// addroundkey

void myAES::rotword(uchar column[], int iReihe) {
    uchar tmp = column[0];
    for (int i = 1; i < iReihe; i++) {
        column[i - 1] = column[i];
    }
    column[iReihe - 1] = tmp;
} // rotword

void myAES::schluesselexpansion(uchar matrix[][44], int iReihe, int iSpalte, int iLaenge) {
    // Alle Spalten durchlaufen
    int pos = 0;

    for (int i = 0; i < iSpalte; i++) {
        if (i < 4) { // Schluessel in erste vier Spalten kopieren
            for (int k = 0; k < iReihe && pos < iLaenge; k++) {
                matrix[k][i] = schluessel[pos];
                pos++;
                //cout << hex << "matrix[" << k << "][" << i << "] = " << (int) matrix[k][i] << endl;
            }
        } else { // i > 4
            if (i % 4 == 0) {// erste Spalte eines Schluessels
                // Spalte in Hilfsarray kopieren
                uchar tmp[iReihe]; // i-1
                uchar tmp2[iReihe]; // i-4
                for (int k = 0; k < iReihe; k++) {
                    tmp[k] = matrix[k][i - 1];
                    tmp2[k] = matrix[k][i - 4];
                }

                rotword(tmp, iReihe);

                subbytes(Sbox, tmp, iReihe);

                // Spalte[i-4] XOR subbytes[rotword[i-i]
                for (int k = 0; k < iReihe; k++) {
                    tmp[k] = tmp[k] ^ tmp2[k];
                }

                // tmp[0] XOR (i/4)
                tmp[0] = tmp[0] ^ Rcon[i / iReihe];

                // tmp[k] an Spalte[k][i] kopieren
                for (int k = 0; k < iReihe; k++) {
                    matrix[k][i] = tmp[k];
                }

            } else {
                //cout << "i " << i << endl;
                for (int k = 0; k < iReihe; k++) {
                    matrix[k][i] = matrix[k][i - 4] ^ matrix[k][i - 1];
                }
            }
        }
    }
}// schluesselexpansion

void myAES::shiftrows() {
    uchar copys[16] = {};

    //reihe 1   
    copys[0] = ciphertext[0];
    copys[4] = ciphertext[4];
    copys[8] = ciphertext[8];
    copys[12] = ciphertext[12];

    //reihe 2
    copys[1] = ciphertext[5];
    copys[5] = ciphertext[9];
    copys[9] = ciphertext[13];
    copys[13] = ciphertext[1];

    // reihe 3
    copys[2] = ciphertext[10];
    copys[6] = ciphertext[14];
    copys[10] = ciphertext[2];
    copys[14] = ciphertext[6];

    //reihe 4
    copys[3] = ciphertext[15];
    copys[7] = ciphertext[3];
    copys[11] = ciphertext[7];
    copys[15] = ciphertext[11];

    //umschreiben   
    for (int i = 0; i < 16; i++) {
        ciphertext[i] = copys[i];
    }
}// shiftrows

void myAES::mixcolumns() {
    for (int i = 0; i < 4; i++) {
        uchar sj0 = mix(ciphertext[i * 4], 2)^mix(ciphertext[i * 4 + 1], 3)^mix(ciphertext[i * 4 + 2], 1)^mix(ciphertext[i * 4 + 3], 1);
        uchar sj1 = mix(ciphertext[i * 4], 1)^mix(ciphertext[i * 4 + 1], 2)^mix(ciphertext[i * 4 + 2], 3)^mix(ciphertext[i * 4 + 3], 1);
        uchar sj2 = mix(ciphertext[i * 4], 1)^mix(ciphertext[i * 4 + 1], 1)^mix(ciphertext[i * 4 + 2], 2)^mix(ciphertext[i * 4 + 3], 3);
        uchar sj3 = mix(ciphertext[i * 4], 3)^mix(ciphertext[i * 4 + 1], 1)^mix(ciphertext[i * 4 + 2], 1)^mix(ciphertext[i * 4 + 3], 2);
        ciphertext[i * 4] = sj0;
        ciphertext[i * 4 + 1] = sj1;
        ciphertext[i * 4 + 2] = sj2;
        ciphertext[i * 4 + 3] = sj3;
    }
}// mixcolumns

void myAES::crypt(bool output) {

    // Parameter
    int iRunde = 10;
    int iLaenge = 16;

    // Überschreibe ciphertext um diesen fortan zu verwenden
    for (int i = 0; i < 16; i++) {
        ciphertext[i] = klartext[i];
    }

    // Arraygroesse dynamisch bestimmen
    int arrSize = sizeof (ciphertext) / sizeof (ciphertext[0]);

    // Zwischenspeicherung der Rundenschluessel
    int iReihe = 4;
    int iSpalte = 4 * (iRunde + 1);
    uchar carrRundenschluessel[4][44];

    // Schluessel expandieren
    schluesselexpansion(carrRundenschluessel, iReihe, iSpalte, iLaenge);

    // Vorrunde
    for (int k = 0; k < iLaenge; k++) {
        ciphertext[k] = ciphertext[k] ^ schluessel[k];
    }

    // Durchlaufen der Runden
    for (int i = 1; i < iRunde + 1; i++) {

        // S-Box
        subbytes(Sbox, ciphertext, arrSize);

        // Shift Rows
        shiftrows();

        // Mix Columns
        if (i != (iRunde)) { // kein MixColumns in der letzten Runde
            mixcolumns();
        }

        // Rundenschlüssel addieren
        addRoundKey(ciphertext, carrRundenschluessel, iReihe, iSpalte, i);

    }
}

void myAES::invert_shiftrows() {
    uchar copys[16] = {};

    //reihe 1   
    copys[0] = klartext[0];
    copys[4] = klartext[4];
    copys[8] = klartext[8];
    copys[12] = klartext[12];

    //reihe 2
    copys[1] = klartext[13];
    copys[13] = klartext[9];
    copys[9] = klartext[5];
    copys[5] = klartext[1];

    // reihe 3   
    copys[6] = klartext[14];
    copys[2] = klartext[10];
    copys[14] = klartext[6];
    copys[10] = klartext[2];

    //reihe 4
    copys[11] = klartext[15];
    copys[7] = klartext[11];
    copys[3] = klartext[7];
    copys[15] = klartext[3];

    //umschreiben   
    for (int i = 0; i < 16; i++) {
        klartext[i] = copys[i];
    }
}// invert_shiftrows

void myAES::invert_mixcolumns() {
    for (int i = 0; i < 4; i++) {
        uchar sj0 = gmul(klartext[i * 4], 14)^gmul(klartext[i * 4 + 1], 11)^gmul(klartext[i * 4 + 2], 13)^gmul(klartext[i * 4 + 3], 9);
        uchar sj1 = gmul(klartext[i * 4], 9)^gmul(klartext[i * 4 + 1], 14)^gmul(klartext[i * 4 + 2], 11)^gmul(klartext[i * 4 + 3], 13);
        uchar sj2 = gmul(klartext[i * 4], 13)^gmul(klartext[i * 4 + 1], 9)^gmul(klartext[i * 4 + 2], 14)^gmul(klartext[i * 4 + 3], 11);
        uchar sj3 = gmul(klartext[i * 4], 11)^gmul(klartext[i * 4 + 1], 13)^gmul(klartext[i * 4 + 2], 9)^gmul(klartext[i * 4 + 3], 14);
        klartext[i * 4] = sj0;
        klartext[i * 4 + 1] = sj1;
        klartext[i * 4 + 2] = sj2;
        klartext[i * 4 + 3] = sj3;
    }
}

uchar myAES::gmul(uchar a, uchar b) {
    unsigned char p = 0;
    unsigned char hi;

    for (int i = 0; i < 8; ++i) {
        if ((b & 1) == 1)
            p ^= a;
        hi = (a & 0x80);
        a <<= 1;
        if (hi == 0x80)
            a ^= 0x1b;
        b >>= 1;
    }
    return p;
}

void myAES::decrypt(bool output) {

    // Parameter
    int iRunde = 10;
    int iLaenge = 16;


    // Überschreibe klartext um diesen fortan zu verwenden
    for (int i = 0; i < 16; i++) {
        klartext[i] = ciphertext[i];
    }

    // Arraygroesse dynamisch bestimmen
    int arrSize = sizeof (klartext) / sizeof (klartext[0]);

    // Zwischenspeicherung der Rundenschluessel
    int iReihe = 4;
    int iSpalte = 4 * (iRunde + 1);
    uchar carrRundenschluessel[4][44];

    // Schluessel expandieren
    schluesselexpansion(carrRundenschluessel, iReihe, iSpalte, iLaenge);

    // "neue" Vorrunde
    addRoundKey(klartext, carrRundenschluessel, iReihe, iSpalte, 10);

    // Durchlaufen der Runden
    for (int i = 9; i > 0; i--) {

        // Shift Rows
        invert_shiftrows();

        // S-Box
        subbytes(sbox_inverse, klartext, arrSize);

        // Rundenschlüssel addieren
        addRoundKey(klartext, carrRundenschluessel, iReihe, iSpalte, i);

        // Mix Columns
        if (i != 10) { // kein MixColumns in der letzten Runde
            invert_mixcolumns();
        }
    }

    // Letzte Runde
    invert_shiftrows();
    subbytes(sbox_inverse, klartext, arrSize);

    for (int k = 0; k < iLaenge; k++) {
        klartext[k] = klartext[k] ^ schluessel[k];
    }
}// decrypt

//</editor-fold>

//<editor-fold defaultstate="collapsed" desc="Konstruktur/Destruktor">

myAES::myAES() {
    uchar kt[16] = {0x61, 0x62, 0x62, 0x69, 0x6c, 0x64, 0x75, 0x6e, 0x67, 0x73, 0x6d, 0x61, 0x74, 0x72, 0x69, 0x78};
    uchar s[16] = {0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31};
    //uchar c[16] = {0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31};
    for (int i = 0; i < 16; i++) {
        schluessel[i] = s[i];
        klartext[i] = kt[i];
    }
}

myAES::~myAES() {
}
//</editor-fold>

//<editor-fold defaultstate="collapsed" desc="Manuelle Eingabe">

void enterValues(uchar arr[], string name) {
    string tmp = "";
    int diff = 0;
    cout << name << ": (16 Zeichen):";
    if (cin >> tmp) {

        if (tmp.length() > 16) {
            cerr << "\nWerte fuer den" << name << " zu groß. Trenne nach 16 Zeichen ab.\n(";
            for (int i = 0; i < tmp.length(); i++) {
                if (i == 16) {
                    cerr << " | ";
                }
                cerr << tmp.at(i);
            }
            cout << ")" << endl;
        }

        if (tmp.length() < 16) {
            cerr << "\nWert fuer den Klartext zu klein. Fuelle mit Nullen auf.\n";
            diff = 16 - tmp.length();
            for (int i = 0; i < diff; i++) {
                tmp.push_back('\0');
            }
            cout << endl;
        }

        for (int i = 0; i < 16; i++) {
            arr[i] = tmp[i];
        }
        cout << endl;

    }
}

void myAES::enterKlartext() {
    enterValues(klartext, "Klartext");
}

void myAES::enterSchluessel() {
    enterValues(schluessel, "Schluessel");
}

//</editor-fold>

//<editor-fold defaultstate="collapsed" desc="Set/Get-Methoden">

void myAES::setCiphertext(uchar tmp[16]) {
    for (int i = 0; i < 16; i++) {
        ciphertext[i] = tmp[i];
    }
}

void myAES::setKlartext(uchar tmp[16]) {
    for (int i = 0; i < 16; i++) {
        klartext[i] = tmp[i];
    }
}

void myAES::setSchluessel(uchar tmp[16]) {
    for (int i = 0; i < 16; i++) {
        schluessel[i] = tmp[i];
    }
}

uchar* myAES::getSchluessel() {
    return schluessel;
}

uchar* myAES::getCiphertext() {
    return ciphertext;
}

uchar* myAES::getKlartext() {
    return klartext;
}

//</editor-fold>

myCBC.h


#ifndef MYCBC_H
#define	MYCBC_H
#include "myAES.h"
#include <vector>
class myCBC {
public:
    // Konstruktoren / Destruktoren
    myCBC();
    virtual ~myCBC();
    
    //CBC
    void crypt(bool);
    void decrypt(bool);
    
    // Set/Get-Methoden
    void setKey(uchar[16]);
    void setIV(uchar[16]);
    void setKlartext(vector<uchar>);
    void setCiphertext(vector<uchar>);
    vector<uchar> getKlartext();
    vector<uchar> getCiphertext();
    uchar* getSchluessel();
    uchar* getIV();
    
    // Manuelle Eingabe
    void enterKey();
    void enterIV();
    void enterKlartext();
    
private:
    uchar iv[16];
    uchar key[16];
    vector<uchar> klartext;
    vector<uchar> ciphertext;
};

myCBC.cpp


#include "myCBC.h"
#include <math.h>
#include <iostream>
#include <iomanip>

using namespace std;

uchar* myCBC::getSchluessel() {
    return key;
}

vector<uchar> myCBC::getKlartext() {
    return klartext;
}

void enterValue(uchar arr[], string name) {
    string tmp = "";
    int diff = 0;
    cout << name << ": (16 Zeichen):";
    if (cin >> tmp) {

        if (tmp.length() > 16) {
            cerr << "\nWerte fuer den" << name << " zu groß. Trenne nach 16 Zeichen ab.\n(";
            for (int i = 0; i < tmp.length(); i++) {
                if (i == 16) {
                    cerr << " | ";
                }
                cerr << tmp.at(i);
            }
            cout << ")" << endl;
        }

        if (tmp.length() < 16) {
            cerr << "\nWert fuer den Klartext zu klein. Fuelle mit Nullen auf.\n";
            diff = 16 - tmp.length();
            for (int i = 0; i < diff; i++) {
                tmp.push_back('\0');
            }
            cout << endl;
        }

        for (int i = 0; i < 16; i++) {
            arr[i] = tmp[i];
        }
        cout << endl;

    }
}

void myCBC::enterKey() {
    enterValue(key, "Schluessel");
}

void myCBC::enterIV() {
    enterValue(iv, "Initialisierungsvektor");
}

void myCBC::enterKlartext() {
    klartext.clear();
    string tmp = "";
    cout << "Klartext (Beliebig viele Zeichen):";
    if (cin >> tmp) {
        for (int i = 0; i < tmp.size(); i++) {
            klartext.push_back(tmp[i]);
        }
        cout << endl;
    }

    if (tmp.size() % 16 != 0) {
        cerr << "\nLetzter Klartext-Block nicht vollstaendig. Fuelle mit Nullen auf.\n";
        for (int i = 0; i < 16 - tmp.size() % 16; i++) {
            klartext.push_back('\0');
        }
        cout << endl;
    }
}

myCBC::myCBC() {

    // Default Parameter
    uchar newKey[16] = {0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c};
    uchar newIV[16] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F};
    uchar newKlartext[16] = {0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a};

    // Schluessel setzen
    for (int i = 0; i < 16; i++) {
        key[i] = newKey[i];
    }

    //IV setzen
    for (int i = 0; i < 16; i++) {
        iv[i] = newIV[i];
    }

    // Klartext setzen
    for (int i = 0; i < 16; i++) {
        klartext.push_back(newKlartext[i]);
    }
}

vector<uchar> myCBC::getCiphertext() {
    return ciphertext;
}

void myCBC::decrypt(bool print) {
    klartext.clear();

    uchar tmp_iv[16];
    for (int j = 0; j < 16; j++) {
        tmp_iv[j] = iv[j];
    }
    for (int i = 0; i < ciphertext.size() / 16; i++) {

        myAES a1;

        //Übergabe - Array
        uchar tmp[16];
        for (int k = 0; k < 16; k++) {
            tmp[k] = ciphertext[k + 16 * i];
        }

        // Ciphertext
        a1.setCiphertext(tmp);

        // Schluessel
        a1.setSchluessel(key);

        // decrypt
        a1.decrypt(false);

        // Resultat mit IV addieren / XOR
        for (int f = 0; f < 16; f++) {
            a1.getKlartext()[f] = a1.getKlartext()[f]^tmp_iv[f];
        }

        // Neuen IV festlegen und Klartext eintragen
        for (int l = 0; l < 16; l++) {
            tmp_iv[l] = a1.getCiphertext()[l];
            klartext.push_back(a1.getKlartext()[l]);
        }
    }
}

void myCBC::crypt(bool print) {
    ciphertext.clear();
    uchar tmp_iv[16];
    for (int i = 0; i < 16; i++) {
        tmp_iv[i] = iv[i];
    }

    for (int i = 0; i < klartext.size() / 16; i++) {

        myAES a1;
        a1.setSchluessel(key);

        //XOR in Übergabe - Array
        uchar tmp[16];
        for (int j = 0; j < 16; j++) {
            tmp[j] = klartext[j + 16 * i]^tmp_iv[j];
        }

        // Klartext
        a1.setKlartext(tmp);

        // crypt
        a1.crypt(false);


        for (int j = 0; j < 16; j++) {
            tmp_iv[j] = a1.getCiphertext()[j];
            ciphertext.push_back(a1.getCiphertext()[j]);
        }
    }
}

void myCBC::setKlartext(vector<uchar> kt) {
    // Padding mit 0
    if (kt.size() > klartext.size()) {
        int diff = kt.size() - klartext.size();
        for (int i = 0; i < diff; i++) {
            klartext.push_back(0x00);
        }
    }

    // Werte übertragen
    for (int i = 0; i < kt.size(); i++) {
        klartext.at(i) = kt.at(i);
    }
}

void myCBC::setIV(uchar tmp[16]) {
    for (int i = 0; i < 16; i++) {
        iv[i] = tmp[i];
    }
}

void myCBC::setKey(uchar tmp[16]) {
    for (int i = 0; i < 16; i++) {
        key[i] = tmp[i];
    }
}

myCBC::~myCBC() {
}

myECB.h


#ifndef MYECB_H
#define	MYECB_H

#include "myAES.h"
#include <vector>
class myECB {
public:
    // Konstruktoren / Destruktoren
    myECB();
    virtual ~myECB();
    
    //CBC
    void crypt(bool);
    void decrypt(bool);
    
    // Set/Get-Methoden
    void setKey(uchar[16]);
    void setKlartext(vector<uchar>);
    void setCiphertext(vector<uchar>);
    vector<uchar> getKlartext();
    vector<uchar> getCiphertext();
    uchar* getSchluessel();
    
    // Manuelle Eingabe
    void enterKey();    
    void enterKlartext();

private:
    uchar key[16];
    vector<uchar> klartext;
    vector<uchar> ciphertext;

};

#endif	/* MYECB_H */

myECB.cpp


#include "myECB.h"
#include <iomanip>
#include <iostream>

void myECB::enterKey() {
    string tmp = "";
    int diff = 0;
    cout << "Schluessel (16 Zeichen):";
    if (cin >> tmp) {

        if (tmp.length() > 16) {
            cerr << "\nWerte fuer den Schluessel zu groß. Trenne nach 16 Zeichen ab.\n(";
            for (int i = 0; i < tmp.length(); i++) {
                if (i == 16) {
                    cerr << " | ";
                }
                cerr << tmp.at(i);
            }
            cout << ")" << endl;
        }

        if (tmp.length() < 16) {
            cerr << "\nWert fuer den Klartext zu klein. Fuelle mit Nullen auf.\n";
            diff = 16 - tmp.length();
            for (int i = 0; i < diff; i++) {
                tmp.push_back('\0');
            }
            cout << endl;
        }

        for (int i = 0; i < 16; i++) {
            key[i] = tmp[i];
        }
        cout << endl;
    }
}

vector<uchar> myECB::getKlartext() {
    return klartext;
}

void myECB::enterKlartext() {
    klartext.clear();
    string tmp = "";
    cout << "Klartext (Beliebig viele Zeichen):";
    if (cin >> tmp) {
        for (int i = 0; i < tmp.size(); i++) {
            klartext.push_back(tmp[i]);
        }
        cout << endl;
    }

    if (tmp.size() % 16 != 0) {
        cerr << "\nLetzter Klartext-Block nicht vollstaendig. Fuelle mit Nullen auf.\n";
        for (int i = 0; i < 16 - tmp.size() % 16; i++) {
            klartext.push_back('\0');
        }
        cout << endl;
    }
}

myECB::myECB() {

    // Default Parameter
    uchar newKey[16] = {0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c};
    uchar newKlartext[16] = {0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a};

    // Schluessel setzen
    for (int i = 0; i < 16; i++) {
        key[i] = newKey[i];
    }

    // Klartext setzen
    for (int i = 0; i < 16; i++) {
        klartext.push_back(newKlartext[i]);
    }
}

vector<uchar> myECB::getCiphertext() {
    return ciphertext;
}

void myECB::decrypt(bool print) {
    klartext.clear();

    for (int i = 0; i < ciphertext.size() / 16; i++) {

        myAES a1;

        //Übergabe - Array
        uchar tmp[16];
        for (int j = 0; j < 16; j++) {
            tmp[j] = ciphertext[j + 16 * i];
        }

        // Ciphertext
        a1.setCiphertext(tmp);

        // Schluessel
        a1.setSchluessel(key);

        // crypt
        a1.decrypt(false);

        // Resultat mit IV addieren
        for (int j = 0; j < 16; j++) {
            klartext.push_back(a1.getKlartext()[j]);
        }
    }
}

void myECB::crypt(bool print) {
    ciphertext.clear();

    for (int i = 0; i < klartext.size() / 16; i++) {

        myAES a1;
        a1.setSchluessel(key);

        //XOR in Übergabe - Array
        uchar tmp[16];
        for (int j = 0; j < 16; j++) {
            tmp[j] = klartext[j + 16 * i]; //^tmp_iv[j];
        }

        // Klartext
        a1.setKlartext(tmp);

        // crypt
        a1.crypt(false);


        for (int j = 0; j < 16; j++) {
            ciphertext.push_back(a1.getCiphertext()[j]);
        }
    }
}

void myECB::setKlartext(vector<uchar> kt) {
    if (kt.size() > klartext.size()) {
        int diff = kt.size() - klartext.size();
        for (int i = 0; i < diff; i++) {
            klartext.push_back(0x00);
        }
    }
    for (int i = 0; i < kt.size(); i++) {
        klartext.at(i) = kt.at(i);
    }
}

void myECB::setKey(uchar tmp[16]) {
    for (int i = 0; i < 16; i++) {
        key[i] = tmp[i];
    }
}

myECB::~myECB() {
}

myGUI.h


#ifndef MYGUI_H
#define	MYGUI_H

#include <iostream>
#include "myCBC.h"
#include "myECB.h"

class myGUI {
public:
    // Menu
    myGUI();
    void menuAES();
    void menuCBC();
    void menuECB();
    // Tests
    bool checkAES();
    bool checkCBC();
    bool checkECB();
    virtual ~myGUI();
private:
};

#endif	/* MYGUI_H */

myGUI.cpp


//Präprozessor-Direktiven
#include "support.h"
#include "myGUI.h"
#include <vector>
#include <iostream>
#include  <iomanip>


//Namensbereich Auflösung
using namespace std;

// <editor-fold defaultstate="collapsed" desc="Methoden bzgl. AES">

bool myGUI::checkAES() {

    bool returnValue = false;

    // Testvektoren
    uchar schluessel[16] = {0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c};
    uchar klartext_1[16] = {0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a};
    uchar klartext_2[16] = {0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c, 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51};
    uchar klartext_3[16] = {0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11, 0xe5, 0xfb, 0xc1, 0x19, 0x1a, 0x0a, 0x52, 0xef};
    uchar cipher_1[16] = {0x3a, 0xd7, 0x7b, 0xb4, 0x0d, 0x7a, 0x36, 0x60, 0xa8, 0x9e, 0xca, 0xf3, 0x24, 0x66, 0xef, 0x97};
    uchar cipher_2[16] = {0xf5, 0xd3, 0xd5, 0x85, 0x03, 0xb9, 0x69, 0x9d, 0xe7, 0x85, 0x89, 0x5a, 0x96, 0xfd, 0xba, 0xaf};
    uchar cipher_3[16] = {0x43, 0xb1, 0xcd, 0x7f, 0x59, 0x8e, 0xce, 0x23, 0x88, 0x1b, 0x00, 0xe3, 0xed, 0x03, 0x06, 0x88};

    // Test#1
    myAES aes1;
    aes1.setKlartext(klartext_1);
    aes1.setSchluessel(schluessel);
    aes1.crypt(false);

    // Test#2
    myAES aes2;
    aes2.setKlartext(klartext_2);
    aes2.setSchluessel(schluessel);
    aes2.crypt(false);

    // Test#3
    myAES aes3;
    aes3.setKlartext(klartext_3);
    aes3.setSchluessel(schluessel);
    aes3.crypt(false);

    // Prüfung
    bool isWorking = areEqual(aes3.getCiphertext(), cipher_3) && areEqual(aes2.getCiphertext(), cipher_2) && areEqual(aes1.getCiphertext(), cipher_1);
    if (isWorking) {
        returnValue = true;
    } else {

        returnValue = false;
    }
    return returnValue;
}

void myGUI::menuAES() {

    // Variablen initialisieren
    bool run = true;
    unsigned int lowest = 1;
    unsigned int end = 4;
    int input = end;

    // aes initialisieren und verschlüsseln
    myAES aes;
    aes.crypt(false);

    //Menu Eingabe
    while (run) {
        cout << "\nBitte waehlen sie aus:\n";
        cout << "(1) Text verschluesseln \n";
        cout << "(2) Text und Schluessel eingeben \n";
        cout << "(3) Text entschluesseln \n";
        cout << "(4) Zurueck\n";
        cout << "> ";

        // Eingabe überprüfen
        input = validatedInput(lowest, end);

        // Auswahl
        if (input == 1) {
            aes.crypt(true);
            printMatrix(aes.getKlartext(), "Klartext");
            printMatrix(aes.getSchluessel(), "Schluessel");
            printMatrix(aes.getCiphertext(), "Cipher");
        }
        if (input == 2) {
            aes.enterKlartext();
            aes.enterSchluessel();
            aes.crypt(true);
            printMatrix(aes.getKlartext(), "Klartext");
            printMatrix(aes.getSchluessel(), "Schluessel");
            printMatrix(aes.getCiphertext(), "Cipher");
        }
        if (input == 3) {
            aes.decrypt(true);
            printMatrix(aes.getCiphertext(), "Cipher");
            printMatrix(aes.getSchluessel(), "Schluessel");
            printMatrix(aes.getKlartext(), "Klartext");
        }
        if (input == end) {
            run = false;
        }
        if (input == -1) {

            cerr << "Ungueltige Eingabe getätigt.\nBitte nochmal eingeben.\n";
            cout << endl;
        }
    }
}

// </editor-fold>

// <editor-fold defaultstate="collapsed" desc="Methoden bzgl. CBC">

bool myGUI::checkCBC() {
    bool returnValue = false;

    // Test #1  - 16 Byte Testvektoren
    uchar keyB[16] = {0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c};
    uchar ivB[16] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F};
    uchar klartextB1[16] = {0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a};
    uchar ciphertextB1[16] = {0x76, 0x49, 0xab, 0xac, 0x81, 0x19, 0xb2, 0x46, 0xce, 0xe9, 0x8e, 0x9b, 0x12, 0xe9, 0x19, 0x7d};

    // Container 
    vector<uchar> cipherB1;
    vector<uchar> ktB;

    // Container füllen
    for (int i = 0; i < 16; i++) {
        ktB.push_back(klartextB1[i]);
        cipherB1.push_back(ciphertextB1[i]);
    }

    // cbc intialisieren
    myCBC cbcB;
    cbcB.setKey(keyB);
    cbcB.setIV(ivB);
    cbcB.setKlartext(ktB);

    // Verschlüsseln
    cbcB.crypt(false);

    // Test#2 - 32 Byte Testvektoren
    uchar klartextA1[16] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f};
    uchar klartextA2[16] = {0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f};
    uchar ivA[16] = {0x56, 0x2e, 0x17, 0x99, 0x6d, 0x09, 0x3d, 0x28, 0xdd, 0xb3, 0xba, 0x69, 0x5a, 0x2e, 0x6f, 0x58};
    uchar keyA[16] = {0xc2, 0x86, 0x69, 0x6d, 0x88, 0x7c, 0x9a, 0xa0, 0x61, 0x1b, 0xbb, 0x3e, 0x20, 0x25, 0xa4, 0x5a};
    uchar ciphertextA1[16] = {0xd2, 0x96, 0xcd, 0x94, 0xc2, 0xcc, 0xcf, 0x8a, 0x3a, 0x86, 0x30, 0x28, 0xb5, 0xe1, 0xdc, 0x0a};
    uchar ciphertextA2[16] = {0x75, 0x86, 0x60, 0x2d, 0x25, 0x3c, 0xff, 0xf9, 0x1b, 0x82, 0x66, 0xbe, 0xa6, 0xd6, 0x1a, 0xb1};

    // Container
    vector<uchar> cipherA1;
    vector<uchar> test;

    // Container füllen
    for (int i = 0; i < 16; i++) {
        test.push_back(klartextA1[i]);
        cipherA1.push_back(ciphertextA1[i]);
    }

    for (int i = 0; i < 16; i++) {
        test.push_back(klartextA2[i]);
        cipherA1.push_back(ciphertextA2[i]);
    }

    // cbc initialisieren
    myCBC cbcA;
    cbcA.setKey(keyA);
    cbcA.setIV(ivA);
    cbcA.setKlartext(test);

    // Verschlüsseln
    cbcA.crypt(false);

    //Prüfung auf Korrektheit
    bool isWorking = areEqual(cbcA.getCiphertext(), cipherA1) && areEqual(cbcB.getCiphertext(), cipherB1);

    if (isWorking) {
        returnValue = true;
    } else {
        returnValue = false;
    }
    return returnValue;
}

void myGUI::menuCBC() {

    // cbc mit Standard Werten initialisieren
    myCBC cbc;
    cbc.crypt(false);

    // Variablen initialisieren
    bool run = true;
    unsigned int lowest = 1;
    unsigned int end = 5;
    int input = end;

    //Menu Eingabe
    while (run) {
        cout << "\nBitte waehlen sie aus:\n";
        cout << "(1) Text verschluesseln \n";
        cout << "(2) Text und Schluessel eingeben \n";
        cout << "(3) Bild ver- und entschluesseln\n";
        cout << "(4) Text entschluesseln\n";
        cout << "(5) Zurueck\n";
        cout << "> ";

        // Überprüfe Eingabe
        input = validatedInput(lowest, end);

        // Auswahl
        if (input == 1) {
            cbc.crypt(true);
            printMatrix(cbc.getKlartext(), "Klartext");
            printMatrix(cbc.getSchluessel(), "Schluessel");
            printMatrix(cbc.getCiphertext(), "Cipher");
        }
        if (input == 2) {
            cbc.enterIV();
            cbc.enterKey();
            cbc.enterKlartext();
            cbc.crypt(true);
            printMatrix(cbc.getKlartext(), "Klartext");
            printMatrix(cbc.getSchluessel(), "Schluessel");
            printMatrix(cbc.getCiphertext(), "Cipher");
        }
        if (input == 3) {
            //Fülle Vektor mit Punkten
            vector<uchar> myImg;
            fillImage(myImg);

            // Gebe Klartext aus
            printImage(myImg);

            // Setze Klartext, verschlüssle und gebe Cipher aus
            cbc.setKlartext(myImg);
            cbc.crypt(false);
            printImage(cbc.getCiphertext());

            // Entschlüssle und gebe Klartext aus
            cbc.decrypt(false);
            printImage(cbc.getKlartext());
        }
        if (input == 4) {
            cbc.decrypt(true);
            printMatrix(cbc.getCiphertext(), "Cipher");
            printMatrix(cbc.getSchluessel(), "Schluessel");
            printMatrix(cbc.getKlartext(), "Klartext");
        }
        if (input == end) {
            run = false;
        }
        if (input == -1) {
            cerr << "Ungueltige Eingabe getätigt.\nBitte nochmal eingeben.\n";
            cout << endl;
        }
    }

}

// </editor-fold>

// <editor-fold defaultstate="collapsed" desc="Methoden bzgl. ECB">

bool myGUI::checkECB() {
    bool returnValue = false;

    //16 Byte Testvektoren
    uchar schluessel[16] = {0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c};

    uchar klartext_1[16] = {0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a};
    uchar klartext_2[16] = {0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c, 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51};
    uchar klartext_3[16] = {0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11, 0xe5, 0xfb, 0xc1, 0x19, 0x1a, 0x0a, 0x52, 0xef};

    uchar cipher_1[16] = {0x3a, 0xd7, 0x7b, 0xb4, 0x0d, 0x7a, 0x36, 0x60, 0xa8, 0x9e, 0xca, 0xf3, 0x24, 0x66, 0xef, 0x97};
    uchar cipher_2[16] = {0xf5, 0xd3, 0xd5, 0x85, 0x03, 0xb9, 0x69, 0x9d, 0xe7, 0x85, 0x89, 0x5a, 0x96, 0xfd, 0xba, 0xaf};
    uchar cipher_3[16] = {0x43, 0xb1, 0xcd, 0x7f, 0x59, 0x8e, 0xce, 0x23, 0x88, 0x1b, 0x00, 0xe3, 0xed, 0x03, 0x06, 0x88};

    // Container
    vector<uchar> cipherB1;
    vector<uchar> ktB;

    // Fülle Container mit Block 1
    for (int i = 0; i < 16; i++) {
        ktB.push_back(klartext_1[i]);
        cipherB1.push_back(cipher_1[i]);
    }

    // Fülle Container mit Block 2
    for (int i = 0; i < 16; i++) {
        ktB.push_back(klartext_2[i]);
        cipherB1.push_back(cipher_2[i]);
    }

    // Fülle Container mit Block 3
    for (int i = 0; i < 16; i++) {
        ktB.push_back(klartext_3[i]);
        cipherB1.push_back(cipher_3[i]);
    }

    // Verschlüssele mit Hilfe des Schlüssels und den 3 Blöcken
    myECB ecb;
    ecb.setKey(schluessel);
    ecb.setKlartext(ktB);
    ecb.crypt(false);

    //Prüfung auf Gleichheit
    bool isWorking = areEqual(ecb.getCiphertext(), cipherB1);
    if (isWorking) {
        returnValue = true;
    } else {
        returnValue = false;
    }
    return returnValue;
}

void myGUI::menuECB() {


    //Initialisiere ecb mit Standard-Werten
    myECB ecb;
    ecb.crypt(false);

    //Initialisiere Eingabe-Variablen 
    bool run = true;
    unsigned int lowest = 1;
    unsigned int end = 5;
    int input = end;

    //Menu Eingabe
    while (run) {

        cout << "\nBitte waehlen sie aus:\n";
        cout << "(1) Text verschluesseln \n";
        cout << "(2) Text und Schluessel eingeben \n";
        cout << "(3) Bild ver- und entschluesseln\n";
        cout << "(4) Text entschluesseln\n";
        cout << "(5) Zurueck\n";
        cout << "> ";

        // Prüfe Eingabe
        input = validatedInput(lowest, end);

        // Auswahl
        if (input == 1) {
            ecb.crypt(true);
        }
        if (input == 2) {
            ecb.enterKey();
            ecb.enterKlartext();
            ecb.crypt(true);
        }
        if (input == 3) {
            // Erstelle Vektor mit Bildpunkten
            vector<uchar> myImg;
            fillImage(myImg);

            // Gebe Klartext aus
            printImage(myImg);
            ecb.setKlartext(myImg);

            // Verschlpsseln und Gebe Cipher aus
            ecb.crypt(false);
            printImage(ecb.getCiphertext());

            // Entschlüsseln und Klartext ausgeben
            ecb.decrypt(false);
            printImage(ecb.getKlartext());
        }
        if (input == 4) {
            ecb.decrypt(true);
        }
        if (input == end) {
            run = false;
        }
        if (input == -1) {
            cerr << "Ungueltige Eingabe getätigt.\nBitte nochmal eingeben.\n";
            cout << endl;
        }
    }

}

// </editor-fold>

// <editor-fold defaultstate="collapsed" desc="Konstrukturen und Destruktoren">

myGUI::myGUI() {
    //Menu-Variablen

    unsigned int lowest = 1;
    unsigned int end = 4;
    int input = end;
    bool run = true;

    //Start
    cout << "#### Kryptographie Sommersemester 2013 ####\n";
    cout << "Nils Rogmann (725915) und Maximilian Krieg (725922)\n";

    // Begrüßung und Information
    cout << "\nHerzlich willkommen.\n";
    cout << "Das Programm wird nun mit Hilfe von Testvektoren geprueft.\n";

    // AES Check
    cout << "\nAES:\t\t";
    if (checkAES()) {
        cout << "OK";
    } else {
        cerr << "Fehler";
    }

    // CBC Check
    cout << "\nAES mit CBC:\t";
    if (checkCBC()) {
        cout << "OK";
    } else {
        cerr << "Fehler";
    }


    // ECB Check
    cout << "\nAES mit ECB:\t";
    if (checkECB()) {
        cout << "OK";
    } else {
        cerr << "Fehler";
    }

    cout << endl;

    //Menu Eingabe
    while (run) {
        cout << "\nBitte waehlen sie aus:\n";
        cout << "(1) AES\n";
        cout << "(2) AES mit CBC\n";
        cout << "(3) AES mit ECB\n";
        cout << "(4) Programm beenden\n";
        cout << "> ";

        // Prüfe Eingabe auf Gültigkeit
        input = validatedInput(lowest, end);

        // Aufrufe
        if (input == 1) {
            cout << "#### AES ####\n";
            menuAES();
            cout << endl;
        }

        if (input == 2) {
            cout << "#### AES mit CBC ####\n";
            menuCBC();
            cout << endl;
        }


        if (input == 3) {
            cout << "#### AES mit ECB ####\n";
            menuECB();
            cout << endl;
        }

        // Fehler
        if (input == -1) {
            cerr << "Ungueltige Eingabe getätigt.\nBitte nochmal eingeben.\n";
            cout << endl;
        }

        // Beenden
        if (input == end) {

            cout << "Programm wird beendet.\n";
            run = false;
            cout << endl;
        }
    }
}//myGUI

myGUI::~myGUI() {
}//~myGUI

// </editor-fold>

support.h


#include <iostream>
#include <iomanip>
#include <vector>
using namespace std;
typedef unsigned char uchar;

void printMatrix(vector<uchar> v, string name) {
    cout << name << ": \n";

    int add =0;
    for (int j = 0; j < v.size()/16; j++) {
        for (int i = 0; i < 4; i++) {
            cout << hex << setfill('0') << setw(2) << nouppercase << (int) v[i+add] << " ";
            cout << hex << setfill('0') << setw(2) << nouppercase << (int) v[i + 4+add] << " ";
            cout << hex << setfill('0') << setw(2) << nouppercase << (int) v[i + 8+add] << " ";
            cout << hex << setfill('0') << setw(2) << nouppercase << (int) v[i + 12+add] << " ";
            cout << endl;
        }
        add=add+16;
        cout << endl;
    }
    cout << endl;
}

void printMatrix(uchar v[16], string name) {
    cout << name << ": \n";
    for (int i = 0; i < 4; i++) {
        cout << hex << setfill('0') << setw(2) << nouppercase << (int) v[i] << " ";
        cout << hex << setfill('0') << setw(2) << nouppercase << (int) v[i + 4] << " ";
        cout << hex << setfill('0') << setw(2) << nouppercase << (int) v[i + 8] << " ";
        cout << hex << setfill('0') << setw(2) << nouppercase << (int) v[i + 12] << " ";
        cout << endl;
    }
    cout << endl;

    /*
    for (int i=0;i<16;i++)
        cout << hex<<(int) v[i];
     * */
}

int validatedInput(unsigned int lowest, unsigned int highest) {
    int tmp = 0;
    cin.clear();
    if (cin >> tmp) {//Eingabe ist in Ordnung
        cout << endl;
        if (tmp >= lowest && tmp <= highest) {//Eingabe liegt in den Parametern

            return tmp;
        }
    } else {
        // Falsche Inhalte verwerfen und Status zurücksetzen
        string trash = "";
        cin.clear();
        std::getline(std::cin, trash);
    }
    return -1;
}

// 16x16 Matrix ausgeben

void printImage(vector<uchar> myImg) {
    int add = 0;
    for (int j = 0; j < 4; j++) {
        for (int i = 0; i < 4; i++) {
            for (int k = 0; k <= 60; k) {
                cout << hex << setfill('0') << setw(2) << nouppercase << (int) myImg.at(i + k + add) << " ";
                k = k + 4;
            }
            cout << endl;
        }

        add = add + 64;
    }
    cout << endl << endl;
}

// 16x16 Matrix füllen

void fillImage(vector<uchar>& v) {
    // Alles auf 0 setzen
    // Außer den Inneren bereich, diesen auf 1
    for (int y = 0; y < 16; y++) {
        for (int x = 0; x < 16; x++) {
            if (y == 5 || y == 6 || y == 9 || y == 10)
                v.push_back(0x1);
            else {
                v.push_back(0x0);
            }
        }
    }

    //Manuell Randpunkte des Kreises setzen
    v[19] = 0x1;
    v[22] = 0x1;
    v[23] = 0x1;
    v[26] = 0x1;
    v[27] = 0x1;
    v[30] = 0x1;
    v[31] = 0x1;
    v[34] = 0x1;
    v[35] = 0x1;
    v[38] = 0x1;
    v[39] = 0x1;
    v[42] = 0x1;
    v[43] = 0x1;
    v[47] = 0x1;
    v[73] = 0x1;
    v[74] = 0x1;
    v[75] = 0x1;
    v[76] = 0x1;
    v[77] = 0x1;
    v[78] = 0x1;
    v[79] = 0x1;
    v[112] = 0x1;
    v[113] = 0x1;
    v[114] = 0x1;
    v[115] = 0x1;
    v[117] = 0x1;
    v[118] = 0x1;
    v[119] = 0x1;
    v[136] = 0x1;
    v[137] = 0x1;
    v[138] = 0x1;
    v[140] = 0x1;
    v[141] = 0x1;
    v[142] = 0x1;
    v[143] = 0x1;
    v[176] = 0x1;
    v[177] = 0x1;
    v[178] = 0x1;
    v[179] = 0x1;
    v[180] = 0x1;
    v[181] = 0x1;
    v[182] = 0x1;
    v[208] = 0x1;
    v[212] = 0x1;
    v[213] = 0x1;
    v[216] = 0x1;
    v[217] = 0x1;
    v[220] = 0x1;
    v[221] = 0x1;
    v[224] = 0x1;
    v[225] = 0x1;
    v[228] = 0x1;
    v[229] = 0x1;
    v[232] = 0x1;
    v[233] = 0x1;
    v[236] = 0x1;
}

// Gleichheitsprüfung

template<class T>
bool areEqual(T arr1, T arr2) {
    bool tmp = false;
    for (int i = 0; i < 16; i++) {
        if (arr1[i] == arr2[i]) {
            tmp = true;
        } else {
            cout << hex << arr1[i] << "!=" << arr2[i] << endl;
            tmp = false;
            break;
        }
    }
    return tmp;
}

Schreiben Sie einen Kommentar

Ihre E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert

Diese Website verwendet Akismet, um Spam zu reduzieren. Erfahren Sie, wie Ihre Kommentardaten verarbeitet werden.

'); } cout << endl; } } myECB::myECB() { // Default Parameter uchar newKey[16] = {0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c}; uchar newKlartext[16] = {0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a}; // Schluessel setzen for (int i = 0; i < 16; i++) { key[i] = newKey[i]; } // Klartext setzen for (int i = 0; i < 16; i++) { klartext.push_back(newKlartext[i]); } } vector<uchar> myECB::getCiphertext() { return ciphertext; } void myECB::decrypt(bool print) { klartext.clear(); for (int i = 0; i < ciphertext.size() / 16; i++) { myAES a1; //Übergabe - Array uchar tmp[16]; for (int j = 0; j < 16; j++) { tmp[j] = ciphertext[j + 16 * i]; } // Ciphertext a1.setCiphertext(tmp); // Schluessel a1.setSchluessel(key); // crypt a1.decrypt(false); // Resultat mit IV addieren for (int j = 0; j < 16; j++) { klartext.push_back(a1.getKlartext()[j]); } } } void myECB::crypt(bool print) { ciphertext.clear(); for (int i = 0; i < klartext.size() / 16; i++) { myAES a1; a1.setSchluessel(key); //XOR in Übergabe - Array uchar tmp[16]; for (int j = 0; j < 16; j++) { tmp[j] = klartext[j + 16 * i]; //^tmp_iv[j]; } // Klartext a1.setKlartext(tmp); // crypt a1.crypt(false); for (int j = 0; j < 16; j++) { ciphertext.push_back(a1.getCiphertext()[j]); } } } void myECB::setKlartext(vector<uchar> kt) { if (kt.size() > klartext.size()) { int diff = kt.size() - klartext.size(); for (int i = 0; i < diff; i++) { klartext.push_back(0x00); } } for (int i = 0; i < kt.size(); i++) { klartext.at(i) = kt.at(i); } } void myECB::setKey(uchar tmp[16]) { for (int i = 0; i < 16; i++) { key[i] = tmp[i]; } } myECB::~myECB() { }

myGUI.h


#ifndef MYGUI_H
#define	MYGUI_H

#include <iostream>
#include "myCBC.h"
#include "myECB.h"

class myGUI {
public:
    // Menu
    myGUI();
    void menuAES();
    void menuCBC();
    void menuECB();
    // Tests
    bool checkAES();
    bool checkCBC();
    bool checkECB();
    virtual ~myGUI();
private:
};

#endif	/* MYGUI_H */

myGUI.cpp


//Präprozessor-Direktiven
#include "support.h"
#include "myGUI.h"
#include <vector>
#include <iostream>
#include  <iomanip>


//Namensbereich Auflösung
using namespace std;

// <editor-fold defaultstate="collapsed" desc="Methoden bzgl. AES">

bool myGUI::checkAES() {

    bool returnValue = false;

    // Testvektoren
    uchar schluessel[16] = {0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c};
    uchar klartext_1[16] = {0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a};
    uchar klartext_2[16] = {0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c, 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51};
    uchar klartext_3[16] = {0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11, 0xe5, 0xfb, 0xc1, 0x19, 0x1a, 0x0a, 0x52, 0xef};
    uchar cipher_1[16] = {0x3a, 0xd7, 0x7b, 0xb4, 0x0d, 0x7a, 0x36, 0x60, 0xa8, 0x9e, 0xca, 0xf3, 0x24, 0x66, 0xef, 0x97};
    uchar cipher_2[16] = {0xf5, 0xd3, 0xd5, 0x85, 0x03, 0xb9, 0x69, 0x9d, 0xe7, 0x85, 0x89, 0x5a, 0x96, 0xfd, 0xba, 0xaf};
    uchar cipher_3[16] = {0x43, 0xb1, 0xcd, 0x7f, 0x59, 0x8e, 0xce, 0x23, 0x88, 0x1b, 0x00, 0xe3, 0xed, 0x03, 0x06, 0x88};

    // Test#1
    myAES aes1;
    aes1.setKlartext(klartext_1);
    aes1.setSchluessel(schluessel);
    aes1.crypt(false);

    // Test#2
    myAES aes2;
    aes2.setKlartext(klartext_2);
    aes2.setSchluessel(schluessel);
    aes2.crypt(false);

    // Test#3
    myAES aes3;
    aes3.setKlartext(klartext_3);
    aes3.setSchluessel(schluessel);
    aes3.crypt(false);

    // Prüfung
    bool isWorking = areEqual(aes3.getCiphertext(), cipher_3) && areEqual(aes2.getCiphertext(), cipher_2) && areEqual(aes1.getCiphertext(), cipher_1);
    if (isWorking) {
        returnValue = true;
    } else {

        returnValue = false;
    }
    return returnValue;
}

void myGUI::menuAES() {

    // Variablen initialisieren
    bool run = true;
    unsigned int lowest = 1;
    unsigned int end = 4;
    int input = end;

    // aes initialisieren und verschlüsseln
    myAES aes;
    aes.crypt(false);

    //Menu Eingabe
    while (run) {
        cout << "\nBitte waehlen sie aus:\n";
        cout << "(1) Text verschluesseln \n";
        cout << "(2) Text und Schluessel eingeben \n";
        cout << "(3) Text entschluesseln \n";
        cout << "(4) Zurueck\n";
        cout << "> ";

        // Eingabe überprüfen
        input = validatedInput(lowest, end);

        // Auswahl
        if (input == 1) {
            aes.crypt(true);
            printMatrix(aes.getKlartext(), "Klartext");
            printMatrix(aes.getSchluessel(), "Schluessel");
            printMatrix(aes.getCiphertext(), "Cipher");
        }
        if (input == 2) {
            aes.enterKlartext();
            aes.enterSchluessel();
            aes.crypt(true);
            printMatrix(aes.getKlartext(), "Klartext");
            printMatrix(aes.getSchluessel(), "Schluessel");
            printMatrix(aes.getCiphertext(), "Cipher");
        }
        if (input == 3) {
            aes.decrypt(true);
            printMatrix(aes.getCiphertext(), "Cipher");
            printMatrix(aes.getSchluessel(), "Schluessel");
            printMatrix(aes.getKlartext(), "Klartext");
        }
        if (input == end) {
            run = false;
        }
        if (input == -1) {

            cerr << "Ungueltige Eingabe getätigt.\nBitte nochmal eingeben.\n";
            cout << endl;
        }
    }
}

// </editor-fold>

// <editor-fold defaultstate="collapsed" desc="Methoden bzgl. CBC">

bool myGUI::checkCBC() {
    bool returnValue = false;

    // Test #1  - 16 Byte Testvektoren
    uchar keyB[16] = {0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c};
    uchar ivB[16] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F};
    uchar klartextB1[16] = {0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a};
    uchar ciphertextB1[16] = {0x76, 0x49, 0xab, 0xac, 0x81, 0x19, 0xb2, 0x46, 0xce, 0xe9, 0x8e, 0x9b, 0x12, 0xe9, 0x19, 0x7d};

    // Container 
    vector<uchar> cipherB1;
    vector<uchar> ktB;

    // Container füllen
    for (int i = 0; i < 16; i++) {
        ktB.push_back(klartextB1[i]);
        cipherB1.push_back(ciphertextB1[i]);
    }

    // cbc intialisieren
    myCBC cbcB;
    cbcB.setKey(keyB);
    cbcB.setIV(ivB);
    cbcB.setKlartext(ktB);

    // Verschlüsseln
    cbcB.crypt(false);

    // Test#2 - 32 Byte Testvektoren
    uchar klartextA1[16] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f};
    uchar klartextA2[16] = {0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f};
    uchar ivA[16] = {0x56, 0x2e, 0x17, 0x99, 0x6d, 0x09, 0x3d, 0x28, 0xdd, 0xb3, 0xba, 0x69, 0x5a, 0x2e, 0x6f, 0x58};
    uchar keyA[16] = {0xc2, 0x86, 0x69, 0x6d, 0x88, 0x7c, 0x9a, 0xa0, 0x61, 0x1b, 0xbb, 0x3e, 0x20, 0x25, 0xa4, 0x5a};
    uchar ciphertextA1[16] = {0xd2, 0x96, 0xcd, 0x94, 0xc2, 0xcc, 0xcf, 0x8a, 0x3a, 0x86, 0x30, 0x28, 0xb5, 0xe1, 0xdc, 0x0a};
    uchar ciphertextA2[16] = {0x75, 0x86, 0x60, 0x2d, 0x25, 0x3c, 0xff, 0xf9, 0x1b, 0x82, 0x66, 0xbe, 0xa6, 0xd6, 0x1a, 0xb1};

    // Container
    vector<uchar> cipherA1;
    vector<uchar> test;

    // Container füllen
    for (int i = 0; i < 16; i++) {
        test.push_back(klartextA1[i]);
        cipherA1.push_back(ciphertextA1[i]);
    }

    for (int i = 0; i < 16; i++) {
        test.push_back(klartextA2[i]);
        cipherA1.push_back(ciphertextA2[i]);
    }

    // cbc initialisieren
    myCBC cbcA;
    cbcA.setKey(keyA);
    cbcA.setIV(ivA);
    cbcA.setKlartext(test);

    // Verschlüsseln
    cbcA.crypt(false);

    //Prüfung auf Korrektheit
    bool isWorking = areEqual(cbcA.getCiphertext(), cipherA1) && areEqual(cbcB.getCiphertext(), cipherB1);

    if (isWorking) {
        returnValue = true;
    } else {
        returnValue = false;
    }
    return returnValue;
}

void myGUI::menuCBC() {

    // cbc mit Standard Werten initialisieren
    myCBC cbc;
    cbc.crypt(false);

    // Variablen initialisieren
    bool run = true;
    unsigned int lowest = 1;
    unsigned int end = 5;
    int input = end;

    //Menu Eingabe
    while (run) {
        cout << "\nBitte waehlen sie aus:\n";
        cout << "(1) Text verschluesseln \n";
        cout << "(2) Text und Schluessel eingeben \n";
        cout << "(3) Bild ver- und entschluesseln\n";
        cout << "(4) Text entschluesseln\n";
        cout << "(5) Zurueck\n";
        cout << "> ";

        // Überprüfe Eingabe
        input = validatedInput(lowest, end);

        // Auswahl
        if (input == 1) {
            cbc.crypt(true);
            printMatrix(cbc.getKlartext(), "Klartext");
            printMatrix(cbc.getSchluessel(), "Schluessel");
            printMatrix(cbc.getCiphertext(), "Cipher");
        }
        if (input == 2) {
            cbc.enterIV();
            cbc.enterKey();
            cbc.enterKlartext();
            cbc.crypt(true);
            printMatrix(cbc.getKlartext(), "Klartext");
            printMatrix(cbc.getSchluessel(), "Schluessel");
            printMatrix(cbc.getCiphertext(), "Cipher");
        }
        if (input == 3) {
            //Fülle Vektor mit Punkten
            vector<uchar> myImg;
            fillImage(myImg);

            // Gebe Klartext aus
            printImage(myImg);

            // Setze Klartext, verschlüssle und gebe Cipher aus
            cbc.setKlartext(myImg);
            cbc.crypt(false);
            printImage(cbc.getCiphertext());

            // Entschlüssle und gebe Klartext aus
            cbc.decrypt(false);
            printImage(cbc.getKlartext());
        }
        if (input == 4) {
            cbc.decrypt(true);
            printMatrix(cbc.getCiphertext(), "Cipher");
            printMatrix(cbc.getSchluessel(), "Schluessel");
            printMatrix(cbc.getKlartext(), "Klartext");
        }
        if (input == end) {
            run = false;
        }
        if (input == -1) {
            cerr << "Ungueltige Eingabe getätigt.\nBitte nochmal eingeben.\n";
            cout << endl;
        }
    }

}

// </editor-fold>

// <editor-fold defaultstate="collapsed" desc="Methoden bzgl. ECB">

bool myGUI::checkECB() {
    bool returnValue = false;

    //16 Byte Testvektoren
    uchar schluessel[16] = {0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c};

    uchar klartext_1[16] = {0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a};
    uchar klartext_2[16] = {0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c, 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51};
    uchar klartext_3[16] = {0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11, 0xe5, 0xfb, 0xc1, 0x19, 0x1a, 0x0a, 0x52, 0xef};

    uchar cipher_1[16] = {0x3a, 0xd7, 0x7b, 0xb4, 0x0d, 0x7a, 0x36, 0x60, 0xa8, 0x9e, 0xca, 0xf3, 0x24, 0x66, 0xef, 0x97};
    uchar cipher_2[16] = {0xf5, 0xd3, 0xd5, 0x85, 0x03, 0xb9, 0x69, 0x9d, 0xe7, 0x85, 0x89, 0x5a, 0x96, 0xfd, 0xba, 0xaf};
    uchar cipher_3[16] = {0x43, 0xb1, 0xcd, 0x7f, 0x59, 0x8e, 0xce, 0x23, 0x88, 0x1b, 0x00, 0xe3, 0xed, 0x03, 0x06, 0x88};

    // Container
    vector<uchar> cipherB1;
    vector<uchar> ktB;

    // Fülle Container mit Block 1
    for (int i = 0; i < 16; i++) {
        ktB.push_back(klartext_1[i]);
        cipherB1.push_back(cipher_1[i]);
    }

    // Fülle Container mit Block 2
    for (int i = 0; i < 16; i++) {
        ktB.push_back(klartext_2[i]);
        cipherB1.push_back(cipher_2[i]);
    }

    // Fülle Container mit Block 3
    for (int i = 0; i < 16; i++) {
        ktB.push_back(klartext_3[i]);
        cipherB1.push_back(cipher_3[i]);
    }

    // Verschlüssele mit Hilfe des Schlüssels und den 3 Blöcken
    myECB ecb;
    ecb.setKey(schluessel);
    ecb.setKlartext(ktB);
    ecb.crypt(false);

    //Prüfung auf Gleichheit
    bool isWorking = areEqual(ecb.getCiphertext(), cipherB1);
    if (isWorking) {
        returnValue = true;
    } else {
        returnValue = false;
    }
    return returnValue;
}

void myGUI::menuECB() {


    //Initialisiere ecb mit Standard-Werten
    myECB ecb;
    ecb.crypt(false);

    //Initialisiere Eingabe-Variablen 
    bool run = true;
    unsigned int lowest = 1;
    unsigned int end = 5;
    int input = end;

    //Menu Eingabe
    while (run) {

        cout << "\nBitte waehlen sie aus:\n";
        cout << "(1) Text verschluesseln \n";
        cout << "(2) Text und Schluessel eingeben \n";
        cout << "(3) Bild ver- und entschluesseln\n";
        cout << "(4) Text entschluesseln\n";
        cout << "(5) Zurueck\n";
        cout << "> ";

        // Prüfe Eingabe
        input = validatedInput(lowest, end);

        // Auswahl
        if (input == 1) {
            ecb.crypt(true);
        }
        if (input == 2) {
            ecb.enterKey();
            ecb.enterKlartext();
            ecb.crypt(true);
        }
        if (input == 3) {
            // Erstelle Vektor mit Bildpunkten
            vector<uchar> myImg;
            fillImage(myImg);

            // Gebe Klartext aus
            printImage(myImg);
            ecb.setKlartext(myImg);

            // Verschlpsseln und Gebe Cipher aus
            ecb.crypt(false);
            printImage(ecb.getCiphertext());

            // Entschlüsseln und Klartext ausgeben
            ecb.decrypt(false);
            printImage(ecb.getKlartext());
        }
        if (input == 4) {
            ecb.decrypt(true);
        }
        if (input == end) {
            run = false;
        }
        if (input == -1) {
            cerr << "Ungueltige Eingabe getätigt.\nBitte nochmal eingeben.\n";
            cout << endl;
        }
    }

}

// </editor-fold>

// <editor-fold defaultstate="collapsed" desc="Konstrukturen und Destruktoren">

myGUI::myGUI() {
    //Menu-Variablen

    unsigned int lowest = 1;
    unsigned int end = 4;
    int input = end;
    bool run = true;

    //Start
    cout << "#### Kryptographie Sommersemester 2013 ####\n";
    cout << "Nils Rogmann (725915) und Maximilian Krieg (725922)\n";

    // Begrüßung und Information
    cout << "\nHerzlich willkommen.\n";
    cout << "Das Programm wird nun mit Hilfe von Testvektoren geprueft.\n";

    // AES Check
    cout << "\nAES:\t\t";
    if (checkAES()) {
        cout << "OK";
    } else {
        cerr << "Fehler";
    }

    // CBC Check
    cout << "\nAES mit CBC:\t";
    if (checkCBC()) {
        cout << "OK";
    } else {
        cerr << "Fehler";
    }


    // ECB Check
    cout << "\nAES mit ECB:\t";
    if (checkECB()) {
        cout << "OK";
    } else {
        cerr << "Fehler";
    }

    cout << endl;

    //Menu Eingabe
    while (run) {
        cout << "\nBitte waehlen sie aus:\n";
        cout << "(1) AES\n";
        cout << "(2) AES mit CBC\n";
        cout << "(3) AES mit ECB\n";
        cout << "(4) Programm beenden\n";
        cout << "> ";

        // Prüfe Eingabe auf Gültigkeit
        input = validatedInput(lowest, end);

        // Aufrufe
        if (input == 1) {
            cout << "#### AES ####\n";
            menuAES();
            cout << endl;
        }

        if (input == 2) {
            cout << "#### AES mit CBC ####\n";
            menuCBC();
            cout << endl;
        }


        if (input == 3) {
            cout << "#### AES mit ECB ####\n";
            menuECB();
            cout << endl;
        }

        // Fehler
        if (input == -1) {
            cerr << "Ungueltige Eingabe getätigt.\nBitte nochmal eingeben.\n";
            cout << endl;
        }

        // Beenden
        if (input == end) {

            cout << "Programm wird beendet.\n";
            run = false;
            cout << endl;
        }
    }
}//myGUI

myGUI::~myGUI() {
}//~myGUI

// </editor-fold>

support.h


#include <iostream>
#include <iomanip>
#include <vector>
using namespace std;
typedef unsigned char uchar;

void printMatrix(vector<uchar> v, string name) {
    cout << name << ": \n";

    int add =0;
    for (int j = 0; j < v.size()/16; j++) {
        for (int i = 0; i < 4; i++) {
            cout << hex << setfill('0') << setw(2) << nouppercase << (int) v[i+add] << " ";
            cout << hex << setfill('0') << setw(2) << nouppercase << (int) v[i + 4+add] << " ";
            cout << hex << setfill('0') << setw(2) << nouppercase << (int) v[i + 8+add] << " ";
            cout << hex << setfill('0') << setw(2) << nouppercase << (int) v[i + 12+add] << " ";
            cout << endl;
        }
        add=add+16;
        cout << endl;
    }
    cout << endl;
}

void printMatrix(uchar v[16], string name) {
    cout << name << ": \n";
    for (int i = 0; i < 4; i++) {
        cout << hex << setfill('0') << setw(2) << nouppercase << (int) v[i] << " ";
        cout << hex << setfill('0') << setw(2) << nouppercase << (int) v[i + 4] << " ";
        cout << hex << setfill('0') << setw(2) << nouppercase << (int) v[i + 8] << " ";
        cout << hex << setfill('0') << setw(2) << nouppercase << (int) v[i + 12] << " ";
        cout << endl;
    }
    cout << endl;

    /*
    for (int i=0;i<16;i++)
        cout << hex<<(int) v[i];
     * */
}

int validatedInput(unsigned int lowest, unsigned int highest) {
    int tmp = 0;
    cin.clear();
    if (cin >> tmp) {//Eingabe ist in Ordnung
        cout << endl;
        if (tmp >= lowest && tmp <= highest) {//Eingabe liegt in den Parametern

            return tmp;
        }
    } else {
        // Falsche Inhalte verwerfen und Status zurücksetzen
        string trash = "";
        cin.clear();
        std::getline(std::cin, trash);
    }
    return -1;
}

// 16x16 Matrix ausgeben

void printImage(vector<uchar> myImg) {
    int add = 0;
    for (int j = 0; j < 4; j++) {
        for (int i = 0; i < 4; i++) {
            for (int k = 0; k <= 60; k) {
                cout << hex << setfill('0') << setw(2) << nouppercase << (int) myImg.at(i + k + add) << " ";
                k = k + 4;
            }
            cout << endl;
        }

        add = add + 64;
    }
    cout << endl << endl;
}

// 16x16 Matrix füllen

void fillImage(vector<uchar>& v) {
    // Alles auf 0 setzen
    // Außer den Inneren bereich, diesen auf 1
    for (int y = 0; y < 16; y++) {
        for (int x = 0; x < 16; x++) {
            if (y == 5 || y == 6 || y == 9 || y == 10)
                v.push_back(0x1);
            else {
                v.push_back(0x0);
            }
        }
    }

    //Manuell Randpunkte des Kreises setzen
    v[19] = 0x1;
    v[22] = 0x1;
    v[23] = 0x1;
    v[26] = 0x1;
    v[27] = 0x1;
    v[30] = 0x1;
    v[31] = 0x1;
    v[34] = 0x1;
    v[35] = 0x1;
    v[38] = 0x1;
    v[39] = 0x1;
    v[42] = 0x1;
    v[43] = 0x1;
    v[47] = 0x1;
    v[73] = 0x1;
    v[74] = 0x1;
    v[75] = 0x1;
    v[76] = 0x1;
    v[77] = 0x1;
    v[78] = 0x1;
    v[79] = 0x1;
    v[112] = 0x1;
    v[113] = 0x1;
    v[114] = 0x1;
    v[115] = 0x1;
    v[117] = 0x1;
    v[118] = 0x1;
    v[119] = 0x1;
    v[136] = 0x1;
    v[137] = 0x1;
    v[138] = 0x1;
    v[140] = 0x1;
    v[141] = 0x1;
    v[142] = 0x1;
    v[143] = 0x1;
    v[176] = 0x1;
    v[177] = 0x1;
    v[178] = 0x1;
    v[179] = 0x1;
    v[180] = 0x1;
    v[181] = 0x1;
    v[182] = 0x1;
    v[208] = 0x1;
    v[212] = 0x1;
    v[213] = 0x1;
    v[216] = 0x1;
    v[217] = 0x1;
    v[220] = 0x1;
    v[221] = 0x1;
    v[224] = 0x1;
    v[225] = 0x1;
    v[228] = 0x1;
    v[229] = 0x1;
    v[232] = 0x1;
    v[233] = 0x1;
    v[236] = 0x1;
}

// Gleichheitsprüfung

template<class T>
bool areEqual(T arr1, T arr2) {
    bool tmp = false;
    for (int i = 0; i < 16; i++) {
        if (arr1[i] == arr2[i]) {
            tmp = true;
        } else {
            cout << hex << arr1[i] << "!=" << arr2[i] << endl;
            tmp = false;
            break;
        }
    }
    return tmp;
}

Schreiben Sie einen Kommentar

Ihre E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert

Diese Website verwendet Akismet, um Spam zu reduzieren. Erfahren Sie, wie Ihre Kommentardaten verarbeitet werden.

Index