Skript-Anfang Kryptouebung3 – Seite 1 Skript-Ende Kryptouebung3 – 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('
Skip to content
Kryptologie (Praktikum 4)
Skript-Anfang Kryptouebung3 – Seite 1 Skript-Ende Kryptouebung3 – 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;
}
Um dir ein optimales Erlebnis zu bieten, verwenden wir Technologien wie Cookies, um Geräteinformationen zu speichern und/oder darauf zuzugreifen. Wenn du diesen Technologien zustimmst, können wir Daten wie das Surfverhalten oder eindeutige IDs auf dieser Website verarbeiten. Wenn du deine Zustimmung nicht erteilst oder zurückziehst, können bestimmte Merkmale und Funktionen beeinträchtigt werden.
Die technische Speicherung oder der Zugang ist unbedingt erforderlich für den rechtmäßigen Zweck, die Nutzung eines bestimmten Dienstes zu ermöglichen, der vom Teilnehmer oder Nutzer ausdrücklich gewünscht wird, oder für den alleinigen Zweck, die Übertragung einer Nachricht über ein elektronisches Kommunikationsnetz durchzuführen.
Die technische Speicherung oder der Zugriff ist für den rechtmäßigen Zweck der Speicherung von Präferenzen erforderlich, die nicht vom Abonnenten oder Benutzer angefordert wurden.
Die technische Speicherung oder der Zugriff, der ausschließlich zu statistischen Zwecken erfolgt.
Die technische Speicherung oder der Zugriff, der ausschließlich zu anonymen statistischen Zwecken verwendet wird. Ohne eine Vorladung, die freiwillige Zustimmung deines Internetdienstanbieters oder zusätzliche Aufzeichnungen von Dritten können die zu diesem Zweck gespeicherten oder abgerufenen Informationen allein in der Regel nicht dazu verwendet werden, dich zu identifizieren.
Die technische Speicherung oder der Zugriff ist erforderlich, um Nutzerprofile zu erstellen, um Werbung zu versenden oder um den Nutzer auf einer Website oder über mehrere Websites hinweg zu ähnlichen Marketingzwecken zu verfolgen.
Zustimmung verwalten
');
}
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('
Skip to content
Kryptologie (Praktikum 4)
Skript-Anfang Kryptouebung3 – Seite 1 Skript-Ende Kryptouebung3 – 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;
}
Um dir ein optimales Erlebnis zu bieten, verwenden wir Technologien wie Cookies, um Geräteinformationen zu speichern und/oder darauf zuzugreifen. Wenn du diesen Technologien zustimmst, können wir Daten wie das Surfverhalten oder eindeutige IDs auf dieser Website verarbeiten. Wenn du deine Zustimmung nicht erteilst oder zurückziehst, können bestimmte Merkmale und Funktionen beeinträchtigt werden.
Die technische Speicherung oder der Zugang ist unbedingt erforderlich für den rechtmäßigen Zweck, die Nutzung eines bestimmten Dienstes zu ermöglichen, der vom Teilnehmer oder Nutzer ausdrücklich gewünscht wird, oder für den alleinigen Zweck, die Übertragung einer Nachricht über ein elektronisches Kommunikationsnetz durchzuführen.
Die technische Speicherung oder der Zugriff ist für den rechtmäßigen Zweck der Speicherung von Präferenzen erforderlich, die nicht vom Abonnenten oder Benutzer angefordert wurden.
Die technische Speicherung oder der Zugriff, der ausschließlich zu statistischen Zwecken erfolgt.
Die technische Speicherung oder der Zugriff, der ausschließlich zu anonymen statistischen Zwecken verwendet wird. Ohne eine Vorladung, die freiwillige Zustimmung deines Internetdienstanbieters oder zusätzliche Aufzeichnungen von Dritten können die zu diesem Zweck gespeicherten oder abgerufenen Informationen allein in der Regel nicht dazu verwendet werden, dich zu identifizieren.
Die technische Speicherung oder der Zugriff ist erforderlich, um Nutzerprofile zu erstellen, um Werbung zu versenden oder um den Nutzer auf einer Website oder über mehrere Websites hinweg zu ähnlichen Marketingzwecken zu verfolgen.
Zustimmung verwalten
');
}
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('
Skip to content
Kryptologie (Praktikum 4)
Skript-Anfang Kryptouebung3 – Seite 1 Skript-Ende Kryptouebung3 – 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;
}
Um dir ein optimales Erlebnis zu bieten, verwenden wir Technologien wie Cookies, um Geräteinformationen zu speichern und/oder darauf zuzugreifen. Wenn du diesen Technologien zustimmst, können wir Daten wie das Surfverhalten oder eindeutige IDs auf dieser Website verarbeiten. Wenn du deine Zustimmung nicht erteilst oder zurückziehst, können bestimmte Merkmale und Funktionen beeinträchtigt werden.
Die technische Speicherung oder der Zugang ist unbedingt erforderlich für den rechtmäßigen Zweck, die Nutzung eines bestimmten Dienstes zu ermöglichen, der vom Teilnehmer oder Nutzer ausdrücklich gewünscht wird, oder für den alleinigen Zweck, die Übertragung einer Nachricht über ein elektronisches Kommunikationsnetz durchzuführen.
Die technische Speicherung oder der Zugriff ist für den rechtmäßigen Zweck der Speicherung von Präferenzen erforderlich, die nicht vom Abonnenten oder Benutzer angefordert wurden.
Die technische Speicherung oder der Zugriff, der ausschließlich zu statistischen Zwecken erfolgt.
Die technische Speicherung oder der Zugriff, der ausschließlich zu anonymen statistischen Zwecken verwendet wird. Ohne eine Vorladung, die freiwillige Zustimmung deines Internetdienstanbieters oder zusätzliche Aufzeichnungen von Dritten können die zu diesem Zweck gespeicherten oder abgerufenen Informationen allein in der Regel nicht dazu verwendet werden, dich zu identifizieren.
Die technische Speicherung oder der Zugriff ist erforderlich, um Nutzerprofile zu erstellen, um Werbung zu versenden oder um den Nutzer auf einer Website oder über mehrere Websites hinweg zu ähnlichen Marketingzwecken zu verfolgen.
Zustimmung verwalten
');
}
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('
Skip to content
Kryptologie (Praktikum 4)
Skript-Anfang Kryptouebung3 – Seite 1 Skript-Ende Kryptouebung3 – 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;
}
Um dir ein optimales Erlebnis zu bieten, verwenden wir Technologien wie Cookies, um Geräteinformationen zu speichern und/oder darauf zuzugreifen. Wenn du diesen Technologien zustimmst, können wir Daten wie das Surfverhalten oder eindeutige IDs auf dieser Website verarbeiten. Wenn du deine Zustimmung nicht erteilst oder zurückziehst, können bestimmte Merkmale und Funktionen beeinträchtigt werden.
Die technische Speicherung oder der Zugang ist unbedingt erforderlich für den rechtmäßigen Zweck, die Nutzung eines bestimmten Dienstes zu ermöglichen, der vom Teilnehmer oder Nutzer ausdrücklich gewünscht wird, oder für den alleinigen Zweck, die Übertragung einer Nachricht über ein elektronisches Kommunikationsnetz durchzuführen.
Die technische Speicherung oder der Zugriff ist für den rechtmäßigen Zweck der Speicherung von Präferenzen erforderlich, die nicht vom Abonnenten oder Benutzer angefordert wurden.
Die technische Speicherung oder der Zugriff, der ausschließlich zu statistischen Zwecken erfolgt.
Die technische Speicherung oder der Zugriff, der ausschließlich zu anonymen statistischen Zwecken verwendet wird. Ohne eine Vorladung, die freiwillige Zustimmung deines Internetdienstanbieters oder zusätzliche Aufzeichnungen von Dritten können die zu diesem Zweck gespeicherten oder abgerufenen Informationen allein in der Regel nicht dazu verwendet werden, dich zu identifizieren.
Die technische Speicherung oder der Zugriff ist erforderlich, um Nutzerprofile zu erstellen, um Werbung zu versenden oder um den Nutzer auf einer Website oder über mehrere Websites hinweg zu ähnlichen Marketingzwecken zu verfolgen.
Zustimmung verwalten
');
}
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('
Skip to content
Kryptologie (Praktikum 4)
Skript-Anfang Kryptouebung3 – Seite 1 Skript-Ende Kryptouebung3 – 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;
}
Um dir ein optimales Erlebnis zu bieten, verwenden wir Technologien wie Cookies, um Geräteinformationen zu speichern und/oder darauf zuzugreifen. Wenn du diesen Technologien zustimmst, können wir Daten wie das Surfverhalten oder eindeutige IDs auf dieser Website verarbeiten. Wenn du deine Zustimmung nicht erteilst oder zurückziehst, können bestimmte Merkmale und Funktionen beeinträchtigt werden.
Die technische Speicherung oder der Zugang ist unbedingt erforderlich für den rechtmäßigen Zweck, die Nutzung eines bestimmten Dienstes zu ermöglichen, der vom Teilnehmer oder Nutzer ausdrücklich gewünscht wird, oder für den alleinigen Zweck, die Übertragung einer Nachricht über ein elektronisches Kommunikationsnetz durchzuführen.
Die technische Speicherung oder der Zugriff ist für den rechtmäßigen Zweck der Speicherung von Präferenzen erforderlich, die nicht vom Abonnenten oder Benutzer angefordert wurden.
Die technische Speicherung oder der Zugriff, der ausschließlich zu statistischen Zwecken erfolgt.
Die technische Speicherung oder der Zugriff, der ausschließlich zu anonymen statistischen Zwecken verwendet wird. Ohne eine Vorladung, die freiwillige Zustimmung deines Internetdienstanbieters oder zusätzliche Aufzeichnungen von Dritten können die zu diesem Zweck gespeicherten oder abgerufenen Informationen allein in der Regel nicht dazu verwendet werden, dich zu identifizieren.
Die technische Speicherung oder der Zugriff ist erforderlich, um Nutzerprofile zu erstellen, um Werbung zu versenden oder um den Nutzer auf einer Website oder über mehrere Websites hinweg zu ähnlichen Marketingzwecken zu verfolgen.
Zustimmung verwalten
');
}
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;
}