Skript-Anfang Kryptouebung2 – Seite 1 Skript-Ende Kryptouebung2 – Seite 1
main.cpp
// Präprozessor-Direktiven
#include <cstdlib>
#include <iostream>
#include <iomanip>
#include "myGUI.h"
// Using-Deklarationen
using namespace std;
int main(int argc, char** argv) {
myGUI gui;
}// main
myGUI.h
#ifndef MYGUI_H
#define MYGUI_H
#include <iostream>
#include "myCBC.h"
#include "myECB.h"
class myGUI {
public:
myGUI();
void callAES();
void callCBC();
void callECB();
bool checkAES();
bool checkCBC();
bool checkECB();
int validatedInput(unsigned int, unsigned int);
virtual ~myGUI();
private:
};
#endif /* MYGUI_H */
myGUI.cpp
#include "myGUI.h"
#include <vector>
using namespace std;
bool areEqual(vector<uchar> v1, vector<uchar> v2) {
bool tmp = false;
if (v1.size() == v2.size()) {
for (int i = 0; i < v1.size(); i++) {
if (v1[i] == v2[i]) {
tmp = true;
} else {
cout << hex << v1[i] << "!=" << v2[i] << endl;
tmp = false;
break;
}
}
}
return tmp;
}
bool areEqual(uchar* arr1, uchar* 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;
}
bool myGUI::checkCBC() {
bool returnValue = false;
//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};
vector<uchar> cipherB1;
vector<uchar> ktB;
for (int i = 0; i < 16; i++) {
ktB.push_back(klartextB1[i]);
cipherB1.push_back(ciphertextB1[i]);
}
myCBC cbcB;
cbcB.setKey(keyB);
cbcB.setIV(ivB);
cbcB.setKlartext(ktB);
cbcB.crypt(false);
// 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};
vector<uchar> cipherA1;
vector<uchar> test;
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]);
}
myCBC cbcA;
cbcA.setKey(keyA);
cbcA.setIV(ivA);
cbcA.setKlartext(test);
cbcA.crypt(false);
//Prüfung
bool isWorking = areEqual(cbcA.getCiphertext(), cipherA1) && areEqual(cbcB.getCiphertext(), cipherB1);
if (isWorking) {
returnValue = true;
} else {
returnValue = false;
}
return returnValue;
}
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};
vector<uchar> cipherB1;
vector<uchar> ktB;
for (int i = 0; i < 16; i++) {
ktB.push_back(klartext_1[i]);
cipherB1.push_back(cipher_1[i]);
}
for (int i = 0; i < 16; i++) {
ktB.push_back(klartext_2[i]);
cipherB1.push_back(cipher_2[i]);
}
for (int i = 0; i < 16; i++) {
ktB.push_back(klartext_3[i]);
cipherB1.push_back(cipher_3[i]);
}
myECB ecb;
ecb.setKey(schluessel);
ecb.setKlartext(ktB);
ecb.crypt(false);
//Prüfung
bool isWorking = areEqual(ecb.getCiphertext(), cipherB1);
if (isWorking) {
returnValue = true;
} else {
returnValue = false;
}
return returnValue;
}
bool myGUI::checkAES() {
bool returnValue = false;
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};
myAES aes1;
aes1.setKlartext(klartext_1);
aes1.setSchluessel(schluessel);
aes1.crypt(false);
myAES aes2;
aes2.setKlartext(klartext_2);
aes2.setSchluessel(schluessel);
aes2.crypt(false);
myAES aes3;
aes3.setKlartext(klartext_3);
aes3.setSchluessel(schluessel);
aes3.crypt(false);
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::callAES() {
string RED_start = "3[22;31m";
string RED_end = "3[0m";
myAES aes;
aes.crypt(false);
//myAES aesDecrypt;
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) Text und Schluessel aus Datei laden\n";
cout << "(4) Entschluesseln \n";
cout << "(5) Zurueck\n";
cout << "> ";
input = validatedInput(lowest, end);
if (input == 1) {
aes.crypt(true);
}
if (input == 2) {
aes.enterKlartext();
aes.enterSchluessel();
aes.crypt(true);
}
if (input == 3) {
cerr << RED_start << "Noch nicht implementiert\n" << RED_end;
}
if (input == 4) {
aes.decrypt(true);
}
if (input == 5) {
run = false;
}
if (input == -1) {
cerr << RED_start << "Ungueltige Eingabe getätigt.\nBitte nochmal eingeben.\n" << RED_end;
cout << endl;
}
}
}
void myGUI::callCBC() {
string RED_start = "3[22;31m";
string RED_end = "3[0m";
myCBC cbc;
cbc.crypt(true);
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) Text und Schluessel aus Datei laden\n";
cout << "(4) Text entschluesseln\n";
cout << "(5) Zurueck\n";
cout << "> ";
input = validatedInput(lowest, end);
if (input == 1) {
cbc.crypt(true);
}
if (input == 2) {
cbc.enterIV();
cbc.enterKey();
cbc.enterKlartext();
cbc.crypt(true);
}
if (input == 3) {
cerr << RED_start << "Noch nicht implementiert\n" << RED_end;
}
if (input == 4) {
cbc.decrypt(true);
}
if (input == 5) {
run = false;
}
if (input == -1) {
cerr << RED_start << "Ungueltige Eingabe getätigt.\nBitte nochmal eingeben.\n" << RED_end;
cout << endl;
}
}
}
void myGUI::callECB() {
string RED_start = "3[22;31m";
string RED_end = "3[0m";
myECB ecb;
ecb.crypt(false);
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) Text und Schluessel aus Datei laden\n";
cout << "(4) Text entschluesseln\n";
cout << "(5) Zurueck\n";
cout << "> ";
input = validatedInput(lowest, end);
if (input == 1) {
ecb.crypt(true);
}
if (input == 2) {
ecb.enterKey();
ecb.enterKlartext();
ecb.crypt(true);
}
if (input == 3) {
cerr << RED_start << "Noch nicht implementiert\n" << RED_end;
}
if (input == 4) {
ecb.decrypt(true);
}
if (input == 5) {
run = false;
}
if (input == -1) {
cerr << RED_start << "Ungueltige Eingabe getätigt.\nBitte nochmal eingeben.\n" << RED_end;
cout << endl;
}
}
}
int myGUI::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 {
string trash = "";
cin.clear();
std::getline(std::cin, trash);
}
return -1;
}
myGUI::myGUI() {
string RED_start = "3[22;31m";
string RED_end = "3[0m";
string GREEN_start = "3[22;32m";
string GREEN_end = "3[0m";
//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 geprüft.\n";
// AES Check
cout << "\nAES:\t\t";
if (checkAES()) {
cout << GREEN_start << "OK" << GREEN_end;
} else {
cerr << RED_start << "Fehler" << RED_end;
}
// CBC Check
cout << "\nAES mit CBC:\t";
if (checkCBC()) {
cout << GREEN_start << "OK" << GREEN_end;
} else {
cerr << RED_start << "Fehler" << RED_end;
}
// ECB Check
cout << "\nAES mit ECB:\t";
if (checkECB())
{
cout << GREEN_start << "OK" << GREEN_end;
}
else
{
cerr << RED_start << "Fehler" << RED_end;
}
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 << "> ";
input = validatedInput(lowest, end);
// Aufrufe
if (input == 1) {
cout << GREEN_start << "#### AES ####\n" << GREEN_end;
callAES();
cout << endl;
}
if (input == 2) {
cout << GREEN_start << "#### AES mit CBC ####\n" << GREEN_end;
callCBC();
cout << endl;
}
if (input == 3) {
cout << GREEN_start << "#### AES mit ECB ####\n" << GREEN_end;
callECB();
cout << endl;
}
// Fehler
if (input == -1) {
cerr << RED_start << "Ungueltige Eingabe getätigt.\nBitte nochmal eingeben.\n" << RED_end;
cout << endl;
}
// Beenden
if (input == end) {
cout << "Programm wird beendet.\n";
run = false;
cout << endl;
}
}
}
myGUI::~myGUI() {
}
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();
// AES-Methoden
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);
// Print-Methoden
void printSchluessel();
void printCiphertext();
void printKlartext();
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;
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
};
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 klartext[], int iLaenge, 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++) {
klartext[pos] = klartext[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, arrSize, carrRundenschluessel, iReihe, iSpalte, i);
}
// Ausgabe des Ciphertexts
if (output) {
printSchluessel();
printKlartext();
printCiphertext();
}
}
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);
//printRundenSchluessel(carrRundenschluessel, iReihe, iSpalte);
// "neue" Vorrunde
addRoundKey(klartext, arrSize, 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, arrSize, 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];
}
// Ausgabe des Ciphertexts
if (output) {
printSchluessel();
printCiphertext();
printKlartext();
}
}// decrypt
void myAES::printSchluessel() {
cout << endl << "Schluessel:\n";
for (int i = 0; i < 4; i++)
cout << hex << "\t0x" << (int) schluessel[0 + i] << "\t0x" << (int) schluessel [4 + i] << "\t0x" << (int) schluessel [8 + i] << "\t0x" << (int) schluessel[12 + i] << endl;
cout << endl;
}
void myAES::printCiphertext() {
cout << endl << "Ciphertext:\n";
for (int i = 0; i < 4; i++)
cout << hex << "\t0x" << (int) ciphertext[0 + i] << "\t0x" << (int) ciphertext [4 + i] << "\t0x" << (int) ciphertext [8 + i] << "\t0x" << (int) ciphertext[12 + i] << endl;
cout << endl;
}
void myAES::printKlartext() {
cout << endl << "Klartext:\n";
for (int i = 0; i < 4; i++)
cout << hex << "\t0x" << (int) klartext[0 + i] << "\t0x" << (int) klartext [4 + i] << "\t0x" << (int) klartext [8 + i] << "\t0x" << (int) klartext[12 + i] << endl;
cout << endl;
}
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() {
}
void myAES::enterKlartext() {
string RED_start = "3[22;31m";
string RED_end = "3[0m";
string GREEN_start = "3[22;32m";
string GREEN_end = "3[0m";
string tmp = "";
int diff = 0;
cout << "Klartext (16 Zeichen):";
if (cin >> tmp) {
if (tmp.length() > 16) {
cerr << RED_start << "\nWerte fuer den Klartext zu groß. Trenne nach 16 Zeichen ab.\n(" << GREEN_start;
for (int i = 0; i < tmp.length(); i++) {
if (i == 16) {
cerr << RED_start << " | ";
}
cerr << tmp.at(i);
}
cout << ")" << RED_end << endl;
}
if (tmp.length() < 16) {
cerr << RED_start << "\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 3)
Skript-Anfang Kryptouebung2 – Seite 1 Skript-Ende Kryptouebung2 – Seite 1
main.cpp
// Präprozessor-Direktiven
#include <cstdlib>
#include <iostream>
#include <iomanip>
#include "myGUI.h"
// Using-Deklarationen
using namespace std;
int main(int argc, char** argv) {
myGUI gui;
}// main
myGUI.h
#ifndef MYGUI_H
#define MYGUI_H
#include <iostream>
#include "myCBC.h"
#include "myECB.h"
class myGUI {
public:
myGUI();
void callAES();
void callCBC();
void callECB();
bool checkAES();
bool checkCBC();
bool checkECB();
int validatedInput(unsigned int, unsigned int);
virtual ~myGUI();
private:
};
#endif /* MYGUI_H */
myGUI.cpp
#include "myGUI.h"
#include <vector>
using namespace std;
bool areEqual(vector<uchar> v1, vector<uchar> v2) {
bool tmp = false;
if (v1.size() == v2.size()) {
for (int i = 0; i < v1.size(); i++) {
if (v1[i] == v2[i]) {
tmp = true;
} else {
cout << hex << v1[i] << "!=" << v2[i] << endl;
tmp = false;
break;
}
}
}
return tmp;
}
bool areEqual(uchar* arr1, uchar* 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;
}
bool myGUI::checkCBC() {
bool returnValue = false;
//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};
vector<uchar> cipherB1;
vector<uchar> ktB;
for (int i = 0; i < 16; i++) {
ktB.push_back(klartextB1[i]);
cipherB1.push_back(ciphertextB1[i]);
}
myCBC cbcB;
cbcB.setKey(keyB);
cbcB.setIV(ivB);
cbcB.setKlartext(ktB);
cbcB.crypt(false);
// 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};
vector<uchar> cipherA1;
vector<uchar> test;
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]);
}
myCBC cbcA;
cbcA.setKey(keyA);
cbcA.setIV(ivA);
cbcA.setKlartext(test);
cbcA.crypt(false);
//Prüfung
bool isWorking = areEqual(cbcA.getCiphertext(), cipherA1) && areEqual(cbcB.getCiphertext(), cipherB1);
if (isWorking) {
returnValue = true;
} else {
returnValue = false;
}
return returnValue;
}
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};
vector<uchar> cipherB1;
vector<uchar> ktB;
for (int i = 0; i < 16; i++) {
ktB.push_back(klartext_1[i]);
cipherB1.push_back(cipher_1[i]);
}
for (int i = 0; i < 16; i++) {
ktB.push_back(klartext_2[i]);
cipherB1.push_back(cipher_2[i]);
}
for (int i = 0; i < 16; i++) {
ktB.push_back(klartext_3[i]);
cipherB1.push_back(cipher_3[i]);
}
myECB ecb;
ecb.setKey(schluessel);
ecb.setKlartext(ktB);
ecb.crypt(false);
//Prüfung
bool isWorking = areEqual(ecb.getCiphertext(), cipherB1);
if (isWorking) {
returnValue = true;
} else {
returnValue = false;
}
return returnValue;
}
bool myGUI::checkAES() {
bool returnValue = false;
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};
myAES aes1;
aes1.setKlartext(klartext_1);
aes1.setSchluessel(schluessel);
aes1.crypt(false);
myAES aes2;
aes2.setKlartext(klartext_2);
aes2.setSchluessel(schluessel);
aes2.crypt(false);
myAES aes3;
aes3.setKlartext(klartext_3);
aes3.setSchluessel(schluessel);
aes3.crypt(false);
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::callAES() {
string RED_start = "\033[22;31m";
string RED_end = "\033[0m";
myAES aes;
aes.crypt(false);
//myAES aesDecrypt;
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) Text und Schluessel aus Datei laden\n";
cout << "(4) Entschluesseln \n";
cout << "(5) Zurueck\n";
cout << "> ";
input = validatedInput(lowest, end);
if (input == 1) {
aes.crypt(true);
}
if (input == 2) {
aes.enterKlartext();
aes.enterSchluessel();
aes.crypt(true);
}
if (input == 3) {
cerr << RED_start << "Noch nicht implementiert\n" << RED_end;
}
if (input == 4) {
aes.decrypt(true);
}
if (input == 5) {
run = false;
}
if (input == -1) {
cerr << RED_start << "Ungueltige Eingabe getätigt.\nBitte nochmal eingeben.\n" << RED_end;
cout << endl;
}
}
}
void myGUI::callCBC() {
string RED_start = "\033[22;31m";
string RED_end = "\033[0m";
myCBC cbc;
cbc.crypt(true);
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) Text und Schluessel aus Datei laden\n";
cout << "(4) Text entschluesseln\n";
cout << "(5) Zurueck\n";
cout << "> ";
input = validatedInput(lowest, end);
if (input == 1) {
cbc.crypt(true);
}
if (input == 2) {
cbc.enterIV();
cbc.enterKey();
cbc.enterKlartext();
cbc.crypt(true);
}
if (input == 3) {
cerr << RED_start << "Noch nicht implementiert\n" << RED_end;
}
if (input == 4) {
cbc.decrypt(true);
}
if (input == 5) {
run = false;
}
if (input == -1) {
cerr << RED_start << "Ungueltige Eingabe getätigt.\nBitte nochmal eingeben.\n" << RED_end;
cout << endl;
}
}
}
void myGUI::callECB() {
string RED_start = "\033[22;31m";
string RED_end = "\033[0m";
myECB ecb;
ecb.crypt(false);
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) Text und Schluessel aus Datei laden\n";
cout << "(4) Text entschluesseln\n";
cout << "(5) Zurueck\n";
cout << "> ";
input = validatedInput(lowest, end);
if (input == 1) {
ecb.crypt(true);
}
if (input == 2) {
ecb.enterKey();
ecb.enterKlartext();
ecb.crypt(true);
}
if (input == 3) {
cerr << RED_start << "Noch nicht implementiert\n" << RED_end;
}
if (input == 4) {
ecb.decrypt(true);
}
if (input == 5) {
run = false;
}
if (input == -1) {
cerr << RED_start << "Ungueltige Eingabe getätigt.\nBitte nochmal eingeben.\n" << RED_end;
cout << endl;
}
}
}
int myGUI::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 {
string trash = "";
cin.clear();
std::getline(std::cin, trash);
}
return -1;
}
myGUI::myGUI() {
string RED_start = "\033[22;31m";
string RED_end = "\033[0m";
string GREEN_start = "\033[22;32m";
string GREEN_end = "\033[0m";
//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 geprüft.\n";
// AES Check
cout << "\nAES:\t\t";
if (checkAES()) {
cout << GREEN_start << "OK" << GREEN_end;
} else {
cerr << RED_start << "Fehler" << RED_end;
}
// CBC Check
cout << "\nAES mit CBC:\t";
if (checkCBC()) {
cout << GREEN_start << "OK" << GREEN_end;
} else {
cerr << RED_start << "Fehler" << RED_end;
}
// ECB Check
cout << "\nAES mit ECB:\t";
if (checkECB())
{
cout << GREEN_start << "OK" << GREEN_end;
}
else
{
cerr << RED_start << "Fehler" << RED_end;
}
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 << "> ";
input = validatedInput(lowest, end);
// Aufrufe
if (input == 1) {
cout << GREEN_start << "#### AES ####\n" << GREEN_end;
callAES();
cout << endl;
}
if (input == 2) {
cout << GREEN_start << "#### AES mit CBC ####\n" << GREEN_end;
callCBC();
cout << endl;
}
if (input == 3) {
cout << GREEN_start << "#### AES mit ECB ####\n" << GREEN_end;
callECB();
cout << endl;
}
// Fehler
if (input == -1) {
cerr << RED_start << "Ungueltige Eingabe getätigt.\nBitte nochmal eingeben.\n" << RED_end;
cout << endl;
}
// Beenden
if (input == end) {
cout << "Programm wird beendet.\n";
run = false;
cout << endl;
}
}
}
myGUI::~myGUI() {
}
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();
// AES-Methoden
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);
// Print-Methoden
void printSchluessel();
void printCiphertext();
void printKlartext();
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;
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
};
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 klartext[], int iLaenge, 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++) {
klartext[pos] = klartext[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, arrSize, carrRundenschluessel, iReihe, iSpalte, i);
}
// Ausgabe des Ciphertexts
if (output) {
printSchluessel();
printKlartext();
printCiphertext();
}
}
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);
//printRundenSchluessel(carrRundenschluessel, iReihe, iSpalte);
// "neue" Vorrunde
addRoundKey(klartext, arrSize, 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, arrSize, 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];
}
// Ausgabe des Ciphertexts
if (output) {
printSchluessel();
printCiphertext();
printKlartext();
}
}// decrypt
void myAES::printSchluessel() {
cout << endl << "Schluessel:\n";
for (int i = 0; i < 4; i++)
cout << hex << "\t0x" << (int) schluessel[0 + i] << "\t0x" << (int) schluessel [4 + i] << "\t0x" << (int) schluessel [8 + i] << "\t0x" << (int) schluessel[12 + i] << endl;
cout << endl;
}
void myAES::printCiphertext() {
cout << endl << "Ciphertext:\n";
for (int i = 0; i < 4; i++)
cout << hex << "\t0x" << (int) ciphertext[0 + i] << "\t0x" << (int) ciphertext [4 + i] << "\t0x" << (int) ciphertext [8 + i] << "\t0x" << (int) ciphertext[12 + i] << endl;
cout << endl;
}
void myAES::printKlartext() {
cout << endl << "Klartext:\n";
for (int i = 0; i < 4; i++)
cout << hex << "\t0x" << (int) klartext[0 + i] << "\t0x" << (int) klartext [4 + i] << "\t0x" << (int) klartext [8 + i] << "\t0x" << (int) klartext[12 + i] << endl;
cout << endl;
}
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() {
}
void myAES::enterKlartext() {
string RED_start = "\033[22;31m";
string RED_end = "\033[0m";
string GREEN_start = "\033[22;32m";
string GREEN_end = "\033[0m";
string tmp = "";
int diff = 0;
cout << "Klartext (16 Zeichen):";
if (cin >> tmp) {
if (tmp.length() > 16) {
cerr << RED_start << "\nWerte fuer den Klartext zu groß. Trenne nach 16 Zeichen ab.\n(" << GREEN_start;
for (int i = 0; i < tmp.length(); i++) {
if (i == 16) {
cerr << RED_start << " | ";
}
cerr << tmp.at(i);
}
cout << ")" << RED_end << endl;
}
if (tmp.length() < 16) {
cerr << RED_start << "\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 << RED_end << endl;
}
for (int i = 0; i < 16; i++) {
klartext[i] = tmp[i];
}
cout << endl;
}
}
void myAES::enterSchluessel() {
string RED_start = "\033[22;31m";
string RED_end = "\033[0m";
string GREEN_start = "\033[22;32m";
string GREEN_end = "\033[0m";
string tmp = "";
int diff = 0;
cout << "Schluessel (16 Zeichen):";
if (cin >> tmp) {
if (tmp.length() > 16) {
cerr << RED_start << "\nWerte fuer den Schluessel zu groß. Trenne nach 16 Zeichen ab.\n(" << GREEN_start;
for (int i = 0; i < tmp.length(); i++) {
if (i == 16) {
cerr << RED_start << " | ";
}
cerr << tmp.at(i);
}
cout << ")" << RED_end << endl;
}
if (tmp.length() < 16) {
cerr << RED_start << "\nWert fuer den Schluessel zu klein. Fuelle mit Nullen auf.\n";
diff = 16 - tmp.length();
for (int i = 0; i < diff; i++) {
tmp.push_back('\0');
}
cout << RED_end << endl;
}
for (int i = 0; i < 16; i++) {
schluessel[i] = tmp[i];
//cout << hex << tmp[i];
}
cout << endl;
}
}
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;
}
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();
// Print-Methoden
void printSchluessel();
void printCiphertext();
void printKlartext();
private:
//unsigned int stellen;
uchar iv[16];
uchar key[16];
vector<uchar> klartext;
vector<uchar> ciphertext;
};
#endif /* MYCBC_H */
myCBC.cpp
#include "myCBC.h"
void myCBC::enterKey() {
string RED_start = "\033[22;31m";
string RED_end = "\033[0m";
string GREEN_start = "\033[22;32m";
string GREEN_end = "\033[0m";
string tmp = "";
int diff = 0;
cout << "Schluessel (16 Zeichen):";
if (cin >> tmp) {
if (tmp.length() > 16) {
cerr << RED_start << "\nWerte fuer den Schluessel zu groß. Trenne nach 16 Zeichen ab.\n(" << GREEN_start;
for (int i = 0; i < tmp.length(); i++) {
if (i == 16) {
cerr << RED_start << " | ";
}
cerr << tmp.at(i);
}
cout << ")" << RED_end << endl;
}
if (tmp.length() < 16) {
cerr << RED_start << "\nWert fuer den Schluessel zu klein. Fuelle mit Nullen auf.\n";
diff = 16 - tmp.length();
for (int i = 0; i < diff; i++) {
tmp.push_back('\0');
}
cout << RED_end << endl;
}
for (int i = 0; i < 16; i++) {
key[i] = tmp[i];
}
cout << endl;
}
}
void myCBC::enterIV() {
string RED_start = "\033[22;31m";
string RED_end = "\033[0m";
string GREEN_start = "\033[22;32m";
string GREEN_end = "\033[0m";
string tmp = "";
int diff = 0;
cout << "IV (16 Zeichen):";
if (cin >> tmp) {
if (tmp.length() > 16) {
cerr << RED_start << "\nWerte fuer den IV zu groß. Trenne nach 16 Zeichen ab.\n(" << GREEN_start;
for (int i = 0; i < tmp.length(); i++) {
if (i == 16) {
cerr << RED_start << " | ";
}
cerr << tmp.at(i);
}
cout << ")" << RED_end << endl;
}
if (tmp.length() < 16) {
cerr << RED_start << "\nWert fuer den IV zu klein. Fuelle mit Nullen auf.\n";
diff = 16 - tmp.length();
for (int i = 0; i < diff; i++) {
tmp.push_back('\0');
}
cout << RED_end << endl;
}
for (int i = 0; i < 16; i++) {
iv[i] = tmp[i];
}
cout << endl;
}
}
void myCBC::enterKlartext() {
string RED_start = "\033[22;31m";
string RED_end = "\033[0m";
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 << RED_start << "\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 << RED_end << 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]);
}
}
void myCBC::printSchluessel() {
cout << endl << "Schluessel:\n";
for (int i = 0; i < 4; i++)
cout << hex << "\t0x" << (int) key[0 + i] << "\t0x" << (int) key [4 + i] << "\t0x" << (int) key [8 + i] << "\t0x" << (int) key[12 + i] << endl;
cout << endl;
}
void myCBC::printCiphertext() {
cout << endl << "Ciphertext:\n";
for (int i = 0; i < ciphertext.size(); i++) {
cout << std::hex << " 0x" << (int) ciphertext[i];
}
}
void myCBC::printKlartext() {
cout << endl << "Klartext:\n";
for (int i = 0; i < klartext.size(); i++) {
cout << std::hex << " 0x" << (int) klartext[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];
}
//printSchluessel();
//printKlartext();
//printCiphertext();
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++) {
a1.getKlartext()[j] = a1.getKlartext()[j]^tmp_iv[j];
}
for (int j = 0; j < 16; j++) {
tmp_iv[j] = a1.getCiphertext()[j + 16 * i];
klartext.push_back(a1.getKlartext()[j]);
}
}
if (print) {
printSchluessel();
printCiphertext();
printKlartext();
}
}
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]);
}
}
if (print) {
printSchluessel();
printKlartext();
printCiphertext();
}
}
void myCBC::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 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();
// Print-Methoden
void printSchluessel();
void printCiphertext();
void printKlartext();
private:
//unsigned int stellen;
uchar key[16];
vector<uchar> klartext;
vector<uchar> ciphertext;
};
#endif /* MYECB_H */
myECB.cpp
#include "myECB.h"
void myECB::enterKey() {
string RED_start = "\033[22;31m";
string RED_end = "\033[0m";
string GREEN_start = "\033[22;32m";
string GREEN_end = "\033[0m";
string tmp = "";
int diff = 0;
cout << "Schluessel (16 Zeichen):";
if (cin >> tmp) {
if (tmp.length() > 16) {
cerr << RED_start << "\nWerte fuer den Schluessel zu groß. Trenne nach 16 Zeichen ab.\n(" << GREEN_start;
for (int i = 0; i < tmp.length(); i++) {
if (i == 16) {
cerr << RED_start << " | ";
}
cerr << tmp.at(i);
}
cout << ")" << RED_end << endl;
}
if (tmp.length() < 16) {
cerr << RED_start << "\nWert fuer den Schluessel zu klein. Fuelle mit Nullen auf.\n";
diff = 16 - tmp.length();
for (int i = 0; i < diff; i++) {
tmp.push_back('\0');
}
cout << RED_end << endl;
}
for (int i = 0; i < 16; i++) {
key[i] = tmp[i];
}
cout << endl;
}
}
void myECB::enterKlartext() {
string RED_start = "\033[22;31m";
string RED_end = "\033[0m";
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 << RED_start << "\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 << RED_end << 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 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];
}
// Klartext setzen
for (int i = 0; i < 16; i++) {
klartext.push_back(newKlartext[i]);
}
}
void myECB::printSchluessel() {
cout << endl << "Schluessel:\n";
for (int i = 0; i < 4; i++)
cout << hex << "\t0x" << (int) key[0 + i] << "\t0x" << (int) key [4 + i] << "\t0x" << (int) key [8 + i] << "\t0x" << (int) key[12 + i] << endl;
cout << endl;
}
void myECB::printCiphertext() {
cout << endl << "Ciphertext:\n";
for (int i = 0; i < ciphertext.size(); i++) {
cout << std::hex << " 0x" << (int) ciphertext[i];
}
}
void myECB::printKlartext() {
cout << endl << "Klartext:\n";
for (int i = 0; i < klartext.size(); i++) {
cout << std::hex << " 0x" << (int) klartext[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]);
}
}
if (print) {
printSchluessel();
printCiphertext();
printKlartext();
}
}
void myECB::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]);
}
}
if (print) {
printSchluessel();
printKlartext();
printCiphertext();
}
}
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() {
}
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 << RED_end << endl;
}
for (int i = 0; i < 16; i++) {
klartext[i] = tmp[i];
}
cout << endl;
}
}
void myAES::enterSchluessel() {
string RED_start = "3[22;31m";
string RED_end = "3[0m";
string GREEN_start = "3[22;32m";
string GREEN_end = "3[0m";
string tmp = "";
int diff = 0;
cout << "Schluessel (16 Zeichen):";
if (cin >> tmp) {
if (tmp.length() > 16) {
cerr << RED_start << "\nWerte fuer den Schluessel zu groß. Trenne nach 16 Zeichen ab.\n(" << GREEN_start;
for (int i = 0; i < tmp.length(); i++) {
if (i == 16) {
cerr << RED_start << " | ";
}
cerr << tmp.at(i);
}
cout << ")" << RED_end << endl;
}
if (tmp.length() < 16) {
cerr << RED_start << "\nWert fuer den Schluessel 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 3)
Skript-Anfang Kryptouebung2 – Seite 1 Skript-Ende Kryptouebung2 – Seite 1
main.cpp
// Präprozessor-Direktiven
#include <cstdlib>
#include <iostream>
#include <iomanip>
#include "myGUI.h"
// Using-Deklarationen
using namespace std;
int main(int argc, char** argv) {
myGUI gui;
}// main
myGUI.h
#ifndef MYGUI_H
#define MYGUI_H
#include <iostream>
#include "myCBC.h"
#include "myECB.h"
class myGUI {
public:
myGUI();
void callAES();
void callCBC();
void callECB();
bool checkAES();
bool checkCBC();
bool checkECB();
int validatedInput(unsigned int, unsigned int);
virtual ~myGUI();
private:
};
#endif /* MYGUI_H */
myGUI.cpp
#include "myGUI.h"
#include <vector>
using namespace std;
bool areEqual(vector<uchar> v1, vector<uchar> v2) {
bool tmp = false;
if (v1.size() == v2.size()) {
for (int i = 0; i < v1.size(); i++) {
if (v1[i] == v2[i]) {
tmp = true;
} else {
cout << hex << v1[i] << "!=" << v2[i] << endl;
tmp = false;
break;
}
}
}
return tmp;
}
bool areEqual(uchar* arr1, uchar* 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;
}
bool myGUI::checkCBC() {
bool returnValue = false;
//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};
vector<uchar> cipherB1;
vector<uchar> ktB;
for (int i = 0; i < 16; i++) {
ktB.push_back(klartextB1[i]);
cipherB1.push_back(ciphertextB1[i]);
}
myCBC cbcB;
cbcB.setKey(keyB);
cbcB.setIV(ivB);
cbcB.setKlartext(ktB);
cbcB.crypt(false);
// 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};
vector<uchar> cipherA1;
vector<uchar> test;
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]);
}
myCBC cbcA;
cbcA.setKey(keyA);
cbcA.setIV(ivA);
cbcA.setKlartext(test);
cbcA.crypt(false);
//Prüfung
bool isWorking = areEqual(cbcA.getCiphertext(), cipherA1) && areEqual(cbcB.getCiphertext(), cipherB1);
if (isWorking) {
returnValue = true;
} else {
returnValue = false;
}
return returnValue;
}
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};
vector<uchar> cipherB1;
vector<uchar> ktB;
for (int i = 0; i < 16; i++) {
ktB.push_back(klartext_1[i]);
cipherB1.push_back(cipher_1[i]);
}
for (int i = 0; i < 16; i++) {
ktB.push_back(klartext_2[i]);
cipherB1.push_back(cipher_2[i]);
}
for (int i = 0; i < 16; i++) {
ktB.push_back(klartext_3[i]);
cipherB1.push_back(cipher_3[i]);
}
myECB ecb;
ecb.setKey(schluessel);
ecb.setKlartext(ktB);
ecb.crypt(false);
//Prüfung
bool isWorking = areEqual(ecb.getCiphertext(), cipherB1);
if (isWorking) {
returnValue = true;
} else {
returnValue = false;
}
return returnValue;
}
bool myGUI::checkAES() {
bool returnValue = false;
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};
myAES aes1;
aes1.setKlartext(klartext_1);
aes1.setSchluessel(schluessel);
aes1.crypt(false);
myAES aes2;
aes2.setKlartext(klartext_2);
aes2.setSchluessel(schluessel);
aes2.crypt(false);
myAES aes3;
aes3.setKlartext(klartext_3);
aes3.setSchluessel(schluessel);
aes3.crypt(false);
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::callAES() {
string RED_start = "\033[22;31m";
string RED_end = "\033[0m";
myAES aes;
aes.crypt(false);
//myAES aesDecrypt;
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) Text und Schluessel aus Datei laden\n";
cout << "(4) Entschluesseln \n";
cout << "(5) Zurueck\n";
cout << "> ";
input = validatedInput(lowest, end);
if (input == 1) {
aes.crypt(true);
}
if (input == 2) {
aes.enterKlartext();
aes.enterSchluessel();
aes.crypt(true);
}
if (input == 3) {
cerr << RED_start << "Noch nicht implementiert\n" << RED_end;
}
if (input == 4) {
aes.decrypt(true);
}
if (input == 5) {
run = false;
}
if (input == -1) {
cerr << RED_start << "Ungueltige Eingabe getätigt.\nBitte nochmal eingeben.\n" << RED_end;
cout << endl;
}
}
}
void myGUI::callCBC() {
string RED_start = "\033[22;31m";
string RED_end = "\033[0m";
myCBC cbc;
cbc.crypt(true);
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) Text und Schluessel aus Datei laden\n";
cout << "(4) Text entschluesseln\n";
cout << "(5) Zurueck\n";
cout << "> ";
input = validatedInput(lowest, end);
if (input == 1) {
cbc.crypt(true);
}
if (input == 2) {
cbc.enterIV();
cbc.enterKey();
cbc.enterKlartext();
cbc.crypt(true);
}
if (input == 3) {
cerr << RED_start << "Noch nicht implementiert\n" << RED_end;
}
if (input == 4) {
cbc.decrypt(true);
}
if (input == 5) {
run = false;
}
if (input == -1) {
cerr << RED_start << "Ungueltige Eingabe getätigt.\nBitte nochmal eingeben.\n" << RED_end;
cout << endl;
}
}
}
void myGUI::callECB() {
string RED_start = "\033[22;31m";
string RED_end = "\033[0m";
myECB ecb;
ecb.crypt(false);
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) Text und Schluessel aus Datei laden\n";
cout << "(4) Text entschluesseln\n";
cout << "(5) Zurueck\n";
cout << "> ";
input = validatedInput(lowest, end);
if (input == 1) {
ecb.crypt(true);
}
if (input == 2) {
ecb.enterKey();
ecb.enterKlartext();
ecb.crypt(true);
}
if (input == 3) {
cerr << RED_start << "Noch nicht implementiert\n" << RED_end;
}
if (input == 4) {
ecb.decrypt(true);
}
if (input == 5) {
run = false;
}
if (input == -1) {
cerr << RED_start << "Ungueltige Eingabe getätigt.\nBitte nochmal eingeben.\n" << RED_end;
cout << endl;
}
}
}
int myGUI::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 {
string trash = "";
cin.clear();
std::getline(std::cin, trash);
}
return -1;
}
myGUI::myGUI() {
string RED_start = "\033[22;31m";
string RED_end = "\033[0m";
string GREEN_start = "\033[22;32m";
string GREEN_end = "\033[0m";
//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 geprüft.\n";
// AES Check
cout << "\nAES:\t\t";
if (checkAES()) {
cout << GREEN_start << "OK" << GREEN_end;
} else {
cerr << RED_start << "Fehler" << RED_end;
}
// CBC Check
cout << "\nAES mit CBC:\t";
if (checkCBC()) {
cout << GREEN_start << "OK" << GREEN_end;
} else {
cerr << RED_start << "Fehler" << RED_end;
}
// ECB Check
cout << "\nAES mit ECB:\t";
if (checkECB())
{
cout << GREEN_start << "OK" << GREEN_end;
}
else
{
cerr << RED_start << "Fehler" << RED_end;
}
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 << "> ";
input = validatedInput(lowest, end);
// Aufrufe
if (input == 1) {
cout << GREEN_start << "#### AES ####\n" << GREEN_end;
callAES();
cout << endl;
}
if (input == 2) {
cout << GREEN_start << "#### AES mit CBC ####\n" << GREEN_end;
callCBC();
cout << endl;
}
if (input == 3) {
cout << GREEN_start << "#### AES mit ECB ####\n" << GREEN_end;
callECB();
cout << endl;
}
// Fehler
if (input == -1) {
cerr << RED_start << "Ungueltige Eingabe getätigt.\nBitte nochmal eingeben.\n" << RED_end;
cout << endl;
}
// Beenden
if (input == end) {
cout << "Programm wird beendet.\n";
run = false;
cout << endl;
}
}
}
myGUI::~myGUI() {
}
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();
// AES-Methoden
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);
// Print-Methoden
void printSchluessel();
void printCiphertext();
void printKlartext();
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;
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
};
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 klartext[], int iLaenge, 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++) {
klartext[pos] = klartext[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, arrSize, carrRundenschluessel, iReihe, iSpalte, i);
}
// Ausgabe des Ciphertexts
if (output) {
printSchluessel();
printKlartext();
printCiphertext();
}
}
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);
//printRundenSchluessel(carrRundenschluessel, iReihe, iSpalte);
// "neue" Vorrunde
addRoundKey(klartext, arrSize, 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, arrSize, 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];
}
// Ausgabe des Ciphertexts
if (output) {
printSchluessel();
printCiphertext();
printKlartext();
}
}// decrypt
void myAES::printSchluessel() {
cout << endl << "Schluessel:\n";
for (int i = 0; i < 4; i++)
cout << hex << "\t0x" << (int) schluessel[0 + i] << "\t0x" << (int) schluessel [4 + i] << "\t0x" << (int) schluessel [8 + i] << "\t0x" << (int) schluessel[12 + i] << endl;
cout << endl;
}
void myAES::printCiphertext() {
cout << endl << "Ciphertext:\n";
for (int i = 0; i < 4; i++)
cout << hex << "\t0x" << (int) ciphertext[0 + i] << "\t0x" << (int) ciphertext [4 + i] << "\t0x" << (int) ciphertext [8 + i] << "\t0x" << (int) ciphertext[12 + i] << endl;
cout << endl;
}
void myAES::printKlartext() {
cout << endl << "Klartext:\n";
for (int i = 0; i < 4; i++)
cout << hex << "\t0x" << (int) klartext[0 + i] << "\t0x" << (int) klartext [4 + i] << "\t0x" << (int) klartext [8 + i] << "\t0x" << (int) klartext[12 + i] << endl;
cout << endl;
}
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() {
}
void myAES::enterKlartext() {
string RED_start = "\033[22;31m";
string RED_end = "\033[0m";
string GREEN_start = "\033[22;32m";
string GREEN_end = "\033[0m";
string tmp = "";
int diff = 0;
cout << "Klartext (16 Zeichen):";
if (cin >> tmp) {
if (tmp.length() > 16) {
cerr << RED_start << "\nWerte fuer den Klartext zu groß. Trenne nach 16 Zeichen ab.\n(" << GREEN_start;
for (int i = 0; i < tmp.length(); i++) {
if (i == 16) {
cerr << RED_start << " | ";
}
cerr << tmp.at(i);
}
cout << ")" << RED_end << endl;
}
if (tmp.length() < 16) {
cerr << RED_start << "\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 << RED_end << endl;
}
for (int i = 0; i < 16; i++) {
klartext[i] = tmp[i];
}
cout << endl;
}
}
void myAES::enterSchluessel() {
string RED_start = "\033[22;31m";
string RED_end = "\033[0m";
string GREEN_start = "\033[22;32m";
string GREEN_end = "\033[0m";
string tmp = "";
int diff = 0;
cout << "Schluessel (16 Zeichen):";
if (cin >> tmp) {
if (tmp.length() > 16) {
cerr << RED_start << "\nWerte fuer den Schluessel zu groß. Trenne nach 16 Zeichen ab.\n(" << GREEN_start;
for (int i = 0; i < tmp.length(); i++) {
if (i == 16) {
cerr << RED_start << " | ";
}
cerr << tmp.at(i);
}
cout << ")" << RED_end << endl;
}
if (tmp.length() < 16) {
cerr << RED_start << "\nWert fuer den Schluessel zu klein. Fuelle mit Nullen auf.\n";
diff = 16 - tmp.length();
for (int i = 0; i < diff; i++) {
tmp.push_back('\0');
}
cout << RED_end << endl;
}
for (int i = 0; i < 16; i++) {
schluessel[i] = tmp[i];
//cout << hex << tmp[i];
}
cout << endl;
}
}
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;
}
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();
// Print-Methoden
void printSchluessel();
void printCiphertext();
void printKlartext();
private:
//unsigned int stellen;
uchar iv[16];
uchar key[16];
vector<uchar> klartext;
vector<uchar> ciphertext;
};
#endif /* MYCBC_H */
myCBC.cpp
#include "myCBC.h"
void myCBC::enterKey() {
string RED_start = "\033[22;31m";
string RED_end = "\033[0m";
string GREEN_start = "\033[22;32m";
string GREEN_end = "\033[0m";
string tmp = "";
int diff = 0;
cout << "Schluessel (16 Zeichen):";
if (cin >> tmp) {
if (tmp.length() > 16) {
cerr << RED_start << "\nWerte fuer den Schluessel zu groß. Trenne nach 16 Zeichen ab.\n(" << GREEN_start;
for (int i = 0; i < tmp.length(); i++) {
if (i == 16) {
cerr << RED_start << " | ";
}
cerr << tmp.at(i);
}
cout << ")" << RED_end << endl;
}
if (tmp.length() < 16) {
cerr << RED_start << "\nWert fuer den Schluessel zu klein. Fuelle mit Nullen auf.\n";
diff = 16 - tmp.length();
for (int i = 0; i < diff; i++) {
tmp.push_back('\0');
}
cout << RED_end << endl;
}
for (int i = 0; i < 16; i++) {
key[i] = tmp[i];
}
cout << endl;
}
}
void myCBC::enterIV() {
string RED_start = "\033[22;31m";
string RED_end = "\033[0m";
string GREEN_start = "\033[22;32m";
string GREEN_end = "\033[0m";
string tmp = "";
int diff = 0;
cout << "IV (16 Zeichen):";
if (cin >> tmp) {
if (tmp.length() > 16) {
cerr << RED_start << "\nWerte fuer den IV zu groß. Trenne nach 16 Zeichen ab.\n(" << GREEN_start;
for (int i = 0; i < tmp.length(); i++) {
if (i == 16) {
cerr << RED_start << " | ";
}
cerr << tmp.at(i);
}
cout << ")" << RED_end << endl;
}
if (tmp.length() < 16) {
cerr << RED_start << "\nWert fuer den IV zu klein. Fuelle mit Nullen auf.\n";
diff = 16 - tmp.length();
for (int i = 0; i < diff; i++) {
tmp.push_back('\0');
}
cout << RED_end << endl;
}
for (int i = 0; i < 16; i++) {
iv[i] = tmp[i];
}
cout << endl;
}
}
void myCBC::enterKlartext() {
string RED_start = "\033[22;31m";
string RED_end = "\033[0m";
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 << RED_start << "\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 << RED_end << 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]);
}
}
void myCBC::printSchluessel() {
cout << endl << "Schluessel:\n";
for (int i = 0; i < 4; i++)
cout << hex << "\t0x" << (int) key[0 + i] << "\t0x" << (int) key [4 + i] << "\t0x" << (int) key [8 + i] << "\t0x" << (int) key[12 + i] << endl;
cout << endl;
}
void myCBC::printCiphertext() {
cout << endl << "Ciphertext:\n";
for (int i = 0; i < ciphertext.size(); i++) {
cout << std::hex << " 0x" << (int) ciphertext[i];
}
}
void myCBC::printKlartext() {
cout << endl << "Klartext:\n";
for (int i = 0; i < klartext.size(); i++) {
cout << std::hex << " 0x" << (int) klartext[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];
}
//printSchluessel();
//printKlartext();
//printCiphertext();
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++) {
a1.getKlartext()[j] = a1.getKlartext()[j]^tmp_iv[j];
}
for (int j = 0; j < 16; j++) {
tmp_iv[j] = a1.getCiphertext()[j + 16 * i];
klartext.push_back(a1.getKlartext()[j]);
}
}
if (print) {
printSchluessel();
printCiphertext();
printKlartext();
}
}
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]);
}
}
if (print) {
printSchluessel();
printKlartext();
printCiphertext();
}
}
void myCBC::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 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();
// Print-Methoden
void printSchluessel();
void printCiphertext();
void printKlartext();
private:
//unsigned int stellen;
uchar key[16];
vector<uchar> klartext;
vector<uchar> ciphertext;
};
#endif /* MYECB_H */
myECB.cpp
#include "myECB.h"
void myECB::enterKey() {
string RED_start = "\033[22;31m";
string RED_end = "\033[0m";
string GREEN_start = "\033[22;32m";
string GREEN_end = "\033[0m";
string tmp = "";
int diff = 0;
cout << "Schluessel (16 Zeichen):";
if (cin >> tmp) {
if (tmp.length() > 16) {
cerr << RED_start << "\nWerte fuer den Schluessel zu groß. Trenne nach 16 Zeichen ab.\n(" << GREEN_start;
for (int i = 0; i < tmp.length(); i++) {
if (i == 16) {
cerr << RED_start << " | ";
}
cerr << tmp.at(i);
}
cout << ")" << RED_end << endl;
}
if (tmp.length() < 16) {
cerr << RED_start << "\nWert fuer den Schluessel zu klein. Fuelle mit Nullen auf.\n";
diff = 16 - tmp.length();
for (int i = 0; i < diff; i++) {
tmp.push_back('\0');
}
cout << RED_end << endl;
}
for (int i = 0; i < 16; i++) {
key[i] = tmp[i];
}
cout << endl;
}
}
void myECB::enterKlartext() {
string RED_start = "\033[22;31m";
string RED_end = "\033[0m";
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 << RED_start << "\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 << RED_end << 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 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];
}
// Klartext setzen
for (int i = 0; i < 16; i++) {
klartext.push_back(newKlartext[i]);
}
}
void myECB::printSchluessel() {
cout << endl << "Schluessel:\n";
for (int i = 0; i < 4; i++)
cout << hex << "\t0x" << (int) key[0 + i] << "\t0x" << (int) key [4 + i] << "\t0x" << (int) key [8 + i] << "\t0x" << (int) key[12 + i] << endl;
cout << endl;
}
void myECB::printCiphertext() {
cout << endl << "Ciphertext:\n";
for (int i = 0; i < ciphertext.size(); i++) {
cout << std::hex << " 0x" << (int) ciphertext[i];
}
}
void myECB::printKlartext() {
cout << endl << "Klartext:\n";
for (int i = 0; i < klartext.size(); i++) {
cout << std::hex << " 0x" << (int) klartext[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]);
}
}
if (print) {
printSchluessel();
printCiphertext();
printKlartext();
}
}
void myECB::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]);
}
}
if (print) {
printSchluessel();
printKlartext();
printCiphertext();
}
}
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() {
}
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 << RED_end << endl;
}
for (int i = 0; i < 16; i++) {
schluessel[i] = tmp[i];
//cout << hex << tmp[i];
}
cout << endl;
}
}
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;
}
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();
// Print-Methoden
void printSchluessel();
void printCiphertext();
void printKlartext();
private:
//unsigned int stellen;
uchar iv[16];
uchar key[16];
vector<uchar> klartext;
vector<uchar> ciphertext;
};
#endif /* MYCBC_H */
myCBC.cpp
#include "myCBC.h"
void myCBC::enterKey() {
string RED_start = "3[22;31m";
string RED_end = "3[0m";
string GREEN_start = "3[22;32m";
string GREEN_end = "3[0m";
string tmp = "";
int diff = 0;
cout << "Schluessel (16 Zeichen):";
if (cin >> tmp) {
if (tmp.length() > 16) {
cerr << RED_start << "\nWerte fuer den Schluessel zu groß. Trenne nach 16 Zeichen ab.\n(" << GREEN_start;
for (int i = 0; i < tmp.length(); i++) {
if (i == 16) {
cerr << RED_start << " | ";
}
cerr << tmp.at(i);
}
cout << ")" << RED_end << endl;
}
if (tmp.length() < 16) {
cerr << RED_start << "\nWert fuer den Schluessel 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 3)
Skript-Anfang Kryptouebung2 – Seite 1 Skript-Ende Kryptouebung2 – Seite 1
main.cpp
// Präprozessor-Direktiven
#include <cstdlib>
#include <iostream>
#include <iomanip>
#include "myGUI.h"
// Using-Deklarationen
using namespace std;
int main(int argc, char** argv) {
myGUI gui;
}// main
myGUI.h
#ifndef MYGUI_H
#define MYGUI_H
#include <iostream>
#include "myCBC.h"
#include "myECB.h"
class myGUI {
public:
myGUI();
void callAES();
void callCBC();
void callECB();
bool checkAES();
bool checkCBC();
bool checkECB();
int validatedInput(unsigned int, unsigned int);
virtual ~myGUI();
private:
};
#endif /* MYGUI_H */
myGUI.cpp
#include "myGUI.h"
#include <vector>
using namespace std;
bool areEqual(vector<uchar> v1, vector<uchar> v2) {
bool tmp = false;
if (v1.size() == v2.size()) {
for (int i = 0; i < v1.size(); i++) {
if (v1[i] == v2[i]) {
tmp = true;
} else {
cout << hex << v1[i] << "!=" << v2[i] << endl;
tmp = false;
break;
}
}
}
return tmp;
}
bool areEqual(uchar* arr1, uchar* 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;
}
bool myGUI::checkCBC() {
bool returnValue = false;
//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};
vector<uchar> cipherB1;
vector<uchar> ktB;
for (int i = 0; i < 16; i++) {
ktB.push_back(klartextB1[i]);
cipherB1.push_back(ciphertextB1[i]);
}
myCBC cbcB;
cbcB.setKey(keyB);
cbcB.setIV(ivB);
cbcB.setKlartext(ktB);
cbcB.crypt(false);
// 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};
vector<uchar> cipherA1;
vector<uchar> test;
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]);
}
myCBC cbcA;
cbcA.setKey(keyA);
cbcA.setIV(ivA);
cbcA.setKlartext(test);
cbcA.crypt(false);
//Prüfung
bool isWorking = areEqual(cbcA.getCiphertext(), cipherA1) && areEqual(cbcB.getCiphertext(), cipherB1);
if (isWorking) {
returnValue = true;
} else {
returnValue = false;
}
return returnValue;
}
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};
vector<uchar> cipherB1;
vector<uchar> ktB;
for (int i = 0; i < 16; i++) {
ktB.push_back(klartext_1[i]);
cipherB1.push_back(cipher_1[i]);
}
for (int i = 0; i < 16; i++) {
ktB.push_back(klartext_2[i]);
cipherB1.push_back(cipher_2[i]);
}
for (int i = 0; i < 16; i++) {
ktB.push_back(klartext_3[i]);
cipherB1.push_back(cipher_3[i]);
}
myECB ecb;
ecb.setKey(schluessel);
ecb.setKlartext(ktB);
ecb.crypt(false);
//Prüfung
bool isWorking = areEqual(ecb.getCiphertext(), cipherB1);
if (isWorking) {
returnValue = true;
} else {
returnValue = false;
}
return returnValue;
}
bool myGUI::checkAES() {
bool returnValue = false;
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};
myAES aes1;
aes1.setKlartext(klartext_1);
aes1.setSchluessel(schluessel);
aes1.crypt(false);
myAES aes2;
aes2.setKlartext(klartext_2);
aes2.setSchluessel(schluessel);
aes2.crypt(false);
myAES aes3;
aes3.setKlartext(klartext_3);
aes3.setSchluessel(schluessel);
aes3.crypt(false);
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::callAES() {
string RED_start = "\033[22;31m";
string RED_end = "\033[0m";
myAES aes;
aes.crypt(false);
//myAES aesDecrypt;
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) Text und Schluessel aus Datei laden\n";
cout << "(4) Entschluesseln \n";
cout << "(5) Zurueck\n";
cout << "> ";
input = validatedInput(lowest, end);
if (input == 1) {
aes.crypt(true);
}
if (input == 2) {
aes.enterKlartext();
aes.enterSchluessel();
aes.crypt(true);
}
if (input == 3) {
cerr << RED_start << "Noch nicht implementiert\n" << RED_end;
}
if (input == 4) {
aes.decrypt(true);
}
if (input == 5) {
run = false;
}
if (input == -1) {
cerr << RED_start << "Ungueltige Eingabe getätigt.\nBitte nochmal eingeben.\n" << RED_end;
cout << endl;
}
}
}
void myGUI::callCBC() {
string RED_start = "\033[22;31m";
string RED_end = "\033[0m";
myCBC cbc;
cbc.crypt(true);
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) Text und Schluessel aus Datei laden\n";
cout << "(4) Text entschluesseln\n";
cout << "(5) Zurueck\n";
cout << "> ";
input = validatedInput(lowest, end);
if (input == 1) {
cbc.crypt(true);
}
if (input == 2) {
cbc.enterIV();
cbc.enterKey();
cbc.enterKlartext();
cbc.crypt(true);
}
if (input == 3) {
cerr << RED_start << "Noch nicht implementiert\n" << RED_end;
}
if (input == 4) {
cbc.decrypt(true);
}
if (input == 5) {
run = false;
}
if (input == -1) {
cerr << RED_start << "Ungueltige Eingabe getätigt.\nBitte nochmal eingeben.\n" << RED_end;
cout << endl;
}
}
}
void myGUI::callECB() {
string RED_start = "\033[22;31m";
string RED_end = "\033[0m";
myECB ecb;
ecb.crypt(false);
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) Text und Schluessel aus Datei laden\n";
cout << "(4) Text entschluesseln\n";
cout << "(5) Zurueck\n";
cout << "> ";
input = validatedInput(lowest, end);
if (input == 1) {
ecb.crypt(true);
}
if (input == 2) {
ecb.enterKey();
ecb.enterKlartext();
ecb.crypt(true);
}
if (input == 3) {
cerr << RED_start << "Noch nicht implementiert\n" << RED_end;
}
if (input == 4) {
ecb.decrypt(true);
}
if (input == 5) {
run = false;
}
if (input == -1) {
cerr << RED_start << "Ungueltige Eingabe getätigt.\nBitte nochmal eingeben.\n" << RED_end;
cout << endl;
}
}
}
int myGUI::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 {
string trash = "";
cin.clear();
std::getline(std::cin, trash);
}
return -1;
}
myGUI::myGUI() {
string RED_start = "\033[22;31m";
string RED_end = "\033[0m";
string GREEN_start = "\033[22;32m";
string GREEN_end = "\033[0m";
//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 geprüft.\n";
// AES Check
cout << "\nAES:\t\t";
if (checkAES()) {
cout << GREEN_start << "OK" << GREEN_end;
} else {
cerr << RED_start << "Fehler" << RED_end;
}
// CBC Check
cout << "\nAES mit CBC:\t";
if (checkCBC()) {
cout << GREEN_start << "OK" << GREEN_end;
} else {
cerr << RED_start << "Fehler" << RED_end;
}
// ECB Check
cout << "\nAES mit ECB:\t";
if (checkECB())
{
cout << GREEN_start << "OK" << GREEN_end;
}
else
{
cerr << RED_start << "Fehler" << RED_end;
}
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 << "> ";
input = validatedInput(lowest, end);
// Aufrufe
if (input == 1) {
cout << GREEN_start << "#### AES ####\n" << GREEN_end;
callAES();
cout << endl;
}
if (input == 2) {
cout << GREEN_start << "#### AES mit CBC ####\n" << GREEN_end;
callCBC();
cout << endl;
}
if (input == 3) {
cout << GREEN_start << "#### AES mit ECB ####\n" << GREEN_end;
callECB();
cout << endl;
}
// Fehler
if (input == -1) {
cerr << RED_start << "Ungueltige Eingabe getätigt.\nBitte nochmal eingeben.\n" << RED_end;
cout << endl;
}
// Beenden
if (input == end) {
cout << "Programm wird beendet.\n";
run = false;
cout << endl;
}
}
}
myGUI::~myGUI() {
}
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();
// AES-Methoden
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);
// Print-Methoden
void printSchluessel();
void printCiphertext();
void printKlartext();
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;
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
};
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 klartext[], int iLaenge, 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++) {
klartext[pos] = klartext[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, arrSize, carrRundenschluessel, iReihe, iSpalte, i);
}
// Ausgabe des Ciphertexts
if (output) {
printSchluessel();
printKlartext();
printCiphertext();
}
}
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);
//printRundenSchluessel(carrRundenschluessel, iReihe, iSpalte);
// "neue" Vorrunde
addRoundKey(klartext, arrSize, 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, arrSize, 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];
}
// Ausgabe des Ciphertexts
if (output) {
printSchluessel();
printCiphertext();
printKlartext();
}
}// decrypt
void myAES::printSchluessel() {
cout << endl << "Schluessel:\n";
for (int i = 0; i < 4; i++)
cout << hex << "\t0x" << (int) schluessel[0 + i] << "\t0x" << (int) schluessel [4 + i] << "\t0x" << (int) schluessel [8 + i] << "\t0x" << (int) schluessel[12 + i] << endl;
cout << endl;
}
void myAES::printCiphertext() {
cout << endl << "Ciphertext:\n";
for (int i = 0; i < 4; i++)
cout << hex << "\t0x" << (int) ciphertext[0 + i] << "\t0x" << (int) ciphertext [4 + i] << "\t0x" << (int) ciphertext [8 + i] << "\t0x" << (int) ciphertext[12 + i] << endl;
cout << endl;
}
void myAES::printKlartext() {
cout << endl << "Klartext:\n";
for (int i = 0; i < 4; i++)
cout << hex << "\t0x" << (int) klartext[0 + i] << "\t0x" << (int) klartext [4 + i] << "\t0x" << (int) klartext [8 + i] << "\t0x" << (int) klartext[12 + i] << endl;
cout << endl;
}
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() {
}
void myAES::enterKlartext() {
string RED_start = "\033[22;31m";
string RED_end = "\033[0m";
string GREEN_start = "\033[22;32m";
string GREEN_end = "\033[0m";
string tmp = "";
int diff = 0;
cout << "Klartext (16 Zeichen):";
if (cin >> tmp) {
if (tmp.length() > 16) {
cerr << RED_start << "\nWerte fuer den Klartext zu groß. Trenne nach 16 Zeichen ab.\n(" << GREEN_start;
for (int i = 0; i < tmp.length(); i++) {
if (i == 16) {
cerr << RED_start << " | ";
}
cerr << tmp.at(i);
}
cout << ")" << RED_end << endl;
}
if (tmp.length() < 16) {
cerr << RED_start << "\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 << RED_end << endl;
}
for (int i = 0; i < 16; i++) {
klartext[i] = tmp[i];
}
cout << endl;
}
}
void myAES::enterSchluessel() {
string RED_start = "\033[22;31m";
string RED_end = "\033[0m";
string GREEN_start = "\033[22;32m";
string GREEN_end = "\033[0m";
string tmp = "";
int diff = 0;
cout << "Schluessel (16 Zeichen):";
if (cin >> tmp) {
if (tmp.length() > 16) {
cerr << RED_start << "\nWerte fuer den Schluessel zu groß. Trenne nach 16 Zeichen ab.\n(" << GREEN_start;
for (int i = 0; i < tmp.length(); i++) {
if (i == 16) {
cerr << RED_start << " | ";
}
cerr << tmp.at(i);
}
cout << ")" << RED_end << endl;
}
if (tmp.length() < 16) {
cerr << RED_start << "\nWert fuer den Schluessel zu klein. Fuelle mit Nullen auf.\n";
diff = 16 - tmp.length();
for (int i = 0; i < diff; i++) {
tmp.push_back('\0');
}
cout << RED_end << endl;
}
for (int i = 0; i < 16; i++) {
schluessel[i] = tmp[i];
//cout << hex << tmp[i];
}
cout << endl;
}
}
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;
}
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();
// Print-Methoden
void printSchluessel();
void printCiphertext();
void printKlartext();
private:
//unsigned int stellen;
uchar iv[16];
uchar key[16];
vector<uchar> klartext;
vector<uchar> ciphertext;
};
#endif /* MYCBC_H */
myCBC.cpp
#include "myCBC.h"
void myCBC::enterKey() {
string RED_start = "\033[22;31m";
string RED_end = "\033[0m";
string GREEN_start = "\033[22;32m";
string GREEN_end = "\033[0m";
string tmp = "";
int diff = 0;
cout << "Schluessel (16 Zeichen):";
if (cin >> tmp) {
if (tmp.length() > 16) {
cerr << RED_start << "\nWerte fuer den Schluessel zu groß. Trenne nach 16 Zeichen ab.\n(" << GREEN_start;
for (int i = 0; i < tmp.length(); i++) {
if (i == 16) {
cerr << RED_start << " | ";
}
cerr << tmp.at(i);
}
cout << ")" << RED_end << endl;
}
if (tmp.length() < 16) {
cerr << RED_start << "\nWert fuer den Schluessel zu klein. Fuelle mit Nullen auf.\n";
diff = 16 - tmp.length();
for (int i = 0; i < diff; i++) {
tmp.push_back('\0');
}
cout << RED_end << endl;
}
for (int i = 0; i < 16; i++) {
key[i] = tmp[i];
}
cout << endl;
}
}
void myCBC::enterIV() {
string RED_start = "\033[22;31m";
string RED_end = "\033[0m";
string GREEN_start = "\033[22;32m";
string GREEN_end = "\033[0m";
string tmp = "";
int diff = 0;
cout << "IV (16 Zeichen):";
if (cin >> tmp) {
if (tmp.length() > 16) {
cerr << RED_start << "\nWerte fuer den IV zu groß. Trenne nach 16 Zeichen ab.\n(" << GREEN_start;
for (int i = 0; i < tmp.length(); i++) {
if (i == 16) {
cerr << RED_start << " | ";
}
cerr << tmp.at(i);
}
cout << ")" << RED_end << endl;
}
if (tmp.length() < 16) {
cerr << RED_start << "\nWert fuer den IV zu klein. Fuelle mit Nullen auf.\n";
diff = 16 - tmp.length();
for (int i = 0; i < diff; i++) {
tmp.push_back('\0');
}
cout << RED_end << endl;
}
for (int i = 0; i < 16; i++) {
iv[i] = tmp[i];
}
cout << endl;
}
}
void myCBC::enterKlartext() {
string RED_start = "\033[22;31m";
string RED_end = "\033[0m";
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 << RED_start << "\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 << RED_end << 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]);
}
}
void myCBC::printSchluessel() {
cout << endl << "Schluessel:\n";
for (int i = 0; i < 4; i++)
cout << hex << "\t0x" << (int) key[0 + i] << "\t0x" << (int) key [4 + i] << "\t0x" << (int) key [8 + i] << "\t0x" << (int) key[12 + i] << endl;
cout << endl;
}
void myCBC::printCiphertext() {
cout << endl << "Ciphertext:\n";
for (int i = 0; i < ciphertext.size(); i++) {
cout << std::hex << " 0x" << (int) ciphertext[i];
}
}
void myCBC::printKlartext() {
cout << endl << "Klartext:\n";
for (int i = 0; i < klartext.size(); i++) {
cout << std::hex << " 0x" << (int) klartext[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];
}
//printSchluessel();
//printKlartext();
//printCiphertext();
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++) {
a1.getKlartext()[j] = a1.getKlartext()[j]^tmp_iv[j];
}
for (int j = 0; j < 16; j++) {
tmp_iv[j] = a1.getCiphertext()[j + 16 * i];
klartext.push_back(a1.getKlartext()[j]);
}
}
if (print) {
printSchluessel();
printCiphertext();
printKlartext();
}
}
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]);
}
}
if (print) {
printSchluessel();
printKlartext();
printCiphertext();
}
}
void myCBC::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 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();
// Print-Methoden
void printSchluessel();
void printCiphertext();
void printKlartext();
private:
//unsigned int stellen;
uchar key[16];
vector<uchar> klartext;
vector<uchar> ciphertext;
};
#endif /* MYECB_H */
myECB.cpp
#include "myECB.h"
void myECB::enterKey() {
string RED_start = "\033[22;31m";
string RED_end = "\033[0m";
string GREEN_start = "\033[22;32m";
string GREEN_end = "\033[0m";
string tmp = "";
int diff = 0;
cout << "Schluessel (16 Zeichen):";
if (cin >> tmp) {
if (tmp.length() > 16) {
cerr << RED_start << "\nWerte fuer den Schluessel zu groß. Trenne nach 16 Zeichen ab.\n(" << GREEN_start;
for (int i = 0; i < tmp.length(); i++) {
if (i == 16) {
cerr << RED_start << " | ";
}
cerr << tmp.at(i);
}
cout << ")" << RED_end << endl;
}
if (tmp.length() < 16) {
cerr << RED_start << "\nWert fuer den Schluessel zu klein. Fuelle mit Nullen auf.\n";
diff = 16 - tmp.length();
for (int i = 0; i < diff; i++) {
tmp.push_back('\0');
}
cout << RED_end << endl;
}
for (int i = 0; i < 16; i++) {
key[i] = tmp[i];
}
cout << endl;
}
}
void myECB::enterKlartext() {
string RED_start = "\033[22;31m";
string RED_end = "\033[0m";
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 << RED_start << "\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 << RED_end << 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 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];
}
// Klartext setzen
for (int i = 0; i < 16; i++) {
klartext.push_back(newKlartext[i]);
}
}
void myECB::printSchluessel() {
cout << endl << "Schluessel:\n";
for (int i = 0; i < 4; i++)
cout << hex << "\t0x" << (int) key[0 + i] << "\t0x" << (int) key [4 + i] << "\t0x" << (int) key [8 + i] << "\t0x" << (int) key[12 + i] << endl;
cout << endl;
}
void myECB::printCiphertext() {
cout << endl << "Ciphertext:\n";
for (int i = 0; i < ciphertext.size(); i++) {
cout << std::hex << " 0x" << (int) ciphertext[i];
}
}
void myECB::printKlartext() {
cout << endl << "Klartext:\n";
for (int i = 0; i < klartext.size(); i++) {
cout << std::hex << " 0x" << (int) klartext[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]);
}
}
if (print) {
printSchluessel();
printCiphertext();
printKlartext();
}
}
void myECB::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]);
}
}
if (print) {
printSchluessel();
printKlartext();
printCiphertext();
}
}
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() {
}
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 << RED_end << endl;
}
for (int i = 0; i < 16; i++) {
key[i] = tmp[i];
}
cout << endl;
}
}
void myCBC::enterIV() {
string RED_start = "3[22;31m";
string RED_end = "3[0m";
string GREEN_start = "3[22;32m";
string GREEN_end = "3[0m";
string tmp = "";
int diff = 0;
cout << "IV (16 Zeichen):";
if (cin >> tmp) {
if (tmp.length() > 16) {
cerr << RED_start << "\nWerte fuer den IV zu groß. Trenne nach 16 Zeichen ab.\n(" << GREEN_start;
for (int i = 0; i < tmp.length(); i++) {
if (i == 16) {
cerr << RED_start << " | ";
}
cerr << tmp.at(i);
}
cout << ")" << RED_end << endl;
}
if (tmp.length() < 16) {
cerr << RED_start << "\nWert fuer den IV 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 3)
Skript-Anfang Kryptouebung2 – Seite 1 Skript-Ende Kryptouebung2 – Seite 1
main.cpp
// Präprozessor-Direktiven
#include <cstdlib>
#include <iostream>
#include <iomanip>
#include "myGUI.h"
// Using-Deklarationen
using namespace std;
int main(int argc, char** argv) {
myGUI gui;
}// main
myGUI.h
#ifndef MYGUI_H
#define MYGUI_H
#include <iostream>
#include "myCBC.h"
#include "myECB.h"
class myGUI {
public:
myGUI();
void callAES();
void callCBC();
void callECB();
bool checkAES();
bool checkCBC();
bool checkECB();
int validatedInput(unsigned int, unsigned int);
virtual ~myGUI();
private:
};
#endif /* MYGUI_H */
myGUI.cpp
#include "myGUI.h"
#include <vector>
using namespace std;
bool areEqual(vector<uchar> v1, vector<uchar> v2) {
bool tmp = false;
if (v1.size() == v2.size()) {
for (int i = 0; i < v1.size(); i++) {
if (v1[i] == v2[i]) {
tmp = true;
} else {
cout << hex << v1[i] << "!=" << v2[i] << endl;
tmp = false;
break;
}
}
}
return tmp;
}
bool areEqual(uchar* arr1, uchar* 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;
}
bool myGUI::checkCBC() {
bool returnValue = false;
//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};
vector<uchar> cipherB1;
vector<uchar> ktB;
for (int i = 0; i < 16; i++) {
ktB.push_back(klartextB1[i]);
cipherB1.push_back(ciphertextB1[i]);
}
myCBC cbcB;
cbcB.setKey(keyB);
cbcB.setIV(ivB);
cbcB.setKlartext(ktB);
cbcB.crypt(false);
// 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};
vector<uchar> cipherA1;
vector<uchar> test;
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]);
}
myCBC cbcA;
cbcA.setKey(keyA);
cbcA.setIV(ivA);
cbcA.setKlartext(test);
cbcA.crypt(false);
//Prüfung
bool isWorking = areEqual(cbcA.getCiphertext(), cipherA1) && areEqual(cbcB.getCiphertext(), cipherB1);
if (isWorking) {
returnValue = true;
} else {
returnValue = false;
}
return returnValue;
}
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};
vector<uchar> cipherB1;
vector<uchar> ktB;
for (int i = 0; i < 16; i++) {
ktB.push_back(klartext_1[i]);
cipherB1.push_back(cipher_1[i]);
}
for (int i = 0; i < 16; i++) {
ktB.push_back(klartext_2[i]);
cipherB1.push_back(cipher_2[i]);
}
for (int i = 0; i < 16; i++) {
ktB.push_back(klartext_3[i]);
cipherB1.push_back(cipher_3[i]);
}
myECB ecb;
ecb.setKey(schluessel);
ecb.setKlartext(ktB);
ecb.crypt(false);
//Prüfung
bool isWorking = areEqual(ecb.getCiphertext(), cipherB1);
if (isWorking) {
returnValue = true;
} else {
returnValue = false;
}
return returnValue;
}
bool myGUI::checkAES() {
bool returnValue = false;
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};
myAES aes1;
aes1.setKlartext(klartext_1);
aes1.setSchluessel(schluessel);
aes1.crypt(false);
myAES aes2;
aes2.setKlartext(klartext_2);
aes2.setSchluessel(schluessel);
aes2.crypt(false);
myAES aes3;
aes3.setKlartext(klartext_3);
aes3.setSchluessel(schluessel);
aes3.crypt(false);
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::callAES() {
string RED_start = "\033[22;31m";
string RED_end = "\033[0m";
myAES aes;
aes.crypt(false);
//myAES aesDecrypt;
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) Text und Schluessel aus Datei laden\n";
cout << "(4) Entschluesseln \n";
cout << "(5) Zurueck\n";
cout << "> ";
input = validatedInput(lowest, end);
if (input == 1) {
aes.crypt(true);
}
if (input == 2) {
aes.enterKlartext();
aes.enterSchluessel();
aes.crypt(true);
}
if (input == 3) {
cerr << RED_start << "Noch nicht implementiert\n" << RED_end;
}
if (input == 4) {
aes.decrypt(true);
}
if (input == 5) {
run = false;
}
if (input == -1) {
cerr << RED_start << "Ungueltige Eingabe getätigt.\nBitte nochmal eingeben.\n" << RED_end;
cout << endl;
}
}
}
void myGUI::callCBC() {
string RED_start = "\033[22;31m";
string RED_end = "\033[0m";
myCBC cbc;
cbc.crypt(true);
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) Text und Schluessel aus Datei laden\n";
cout << "(4) Text entschluesseln\n";
cout << "(5) Zurueck\n";
cout << "> ";
input = validatedInput(lowest, end);
if (input == 1) {
cbc.crypt(true);
}
if (input == 2) {
cbc.enterIV();
cbc.enterKey();
cbc.enterKlartext();
cbc.crypt(true);
}
if (input == 3) {
cerr << RED_start << "Noch nicht implementiert\n" << RED_end;
}
if (input == 4) {
cbc.decrypt(true);
}
if (input == 5) {
run = false;
}
if (input == -1) {
cerr << RED_start << "Ungueltige Eingabe getätigt.\nBitte nochmal eingeben.\n" << RED_end;
cout << endl;
}
}
}
void myGUI::callECB() {
string RED_start = "\033[22;31m";
string RED_end = "\033[0m";
myECB ecb;
ecb.crypt(false);
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) Text und Schluessel aus Datei laden\n";
cout << "(4) Text entschluesseln\n";
cout << "(5) Zurueck\n";
cout << "> ";
input = validatedInput(lowest, end);
if (input == 1) {
ecb.crypt(true);
}
if (input == 2) {
ecb.enterKey();
ecb.enterKlartext();
ecb.crypt(true);
}
if (input == 3) {
cerr << RED_start << "Noch nicht implementiert\n" << RED_end;
}
if (input == 4) {
ecb.decrypt(true);
}
if (input == 5) {
run = false;
}
if (input == -1) {
cerr << RED_start << "Ungueltige Eingabe getätigt.\nBitte nochmal eingeben.\n" << RED_end;
cout << endl;
}
}
}
int myGUI::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 {
string trash = "";
cin.clear();
std::getline(std::cin, trash);
}
return -1;
}
myGUI::myGUI() {
string RED_start = "\033[22;31m";
string RED_end = "\033[0m";
string GREEN_start = "\033[22;32m";
string GREEN_end = "\033[0m";
//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 geprüft.\n";
// AES Check
cout << "\nAES:\t\t";
if (checkAES()) {
cout << GREEN_start << "OK" << GREEN_end;
} else {
cerr << RED_start << "Fehler" << RED_end;
}
// CBC Check
cout << "\nAES mit CBC:\t";
if (checkCBC()) {
cout << GREEN_start << "OK" << GREEN_end;
} else {
cerr << RED_start << "Fehler" << RED_end;
}
// ECB Check
cout << "\nAES mit ECB:\t";
if (checkECB())
{
cout << GREEN_start << "OK" << GREEN_end;
}
else
{
cerr << RED_start << "Fehler" << RED_end;
}
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 << "> ";
input = validatedInput(lowest, end);
// Aufrufe
if (input == 1) {
cout << GREEN_start << "#### AES ####\n" << GREEN_end;
callAES();
cout << endl;
}
if (input == 2) {
cout << GREEN_start << "#### AES mit CBC ####\n" << GREEN_end;
callCBC();
cout << endl;
}
if (input == 3) {
cout << GREEN_start << "#### AES mit ECB ####\n" << GREEN_end;
callECB();
cout << endl;
}
// Fehler
if (input == -1) {
cerr << RED_start << "Ungueltige Eingabe getätigt.\nBitte nochmal eingeben.\n" << RED_end;
cout << endl;
}
// Beenden
if (input == end) {
cout << "Programm wird beendet.\n";
run = false;
cout << endl;
}
}
}
myGUI::~myGUI() {
}
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();
// AES-Methoden
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);
// Print-Methoden
void printSchluessel();
void printCiphertext();
void printKlartext();
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;
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
};
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 klartext[], int iLaenge, 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++) {
klartext[pos] = klartext[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, arrSize, carrRundenschluessel, iReihe, iSpalte, i);
}
// Ausgabe des Ciphertexts
if (output) {
printSchluessel();
printKlartext();
printCiphertext();
}
}
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);
//printRundenSchluessel(carrRundenschluessel, iReihe, iSpalte);
// "neue" Vorrunde
addRoundKey(klartext, arrSize, 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, arrSize, 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];
}
// Ausgabe des Ciphertexts
if (output) {
printSchluessel();
printCiphertext();
printKlartext();
}
}// decrypt
void myAES::printSchluessel() {
cout << endl << "Schluessel:\n";
for (int i = 0; i < 4; i++)
cout << hex << "\t0x" << (int) schluessel[0 + i] << "\t0x" << (int) schluessel [4 + i] << "\t0x" << (int) schluessel [8 + i] << "\t0x" << (int) schluessel[12 + i] << endl;
cout << endl;
}
void myAES::printCiphertext() {
cout << endl << "Ciphertext:\n";
for (int i = 0; i < 4; i++)
cout << hex << "\t0x" << (int) ciphertext[0 + i] << "\t0x" << (int) ciphertext [4 + i] << "\t0x" << (int) ciphertext [8 + i] << "\t0x" << (int) ciphertext[12 + i] << endl;
cout << endl;
}
void myAES::printKlartext() {
cout << endl << "Klartext:\n";
for (int i = 0; i < 4; i++)
cout << hex << "\t0x" << (int) klartext[0 + i] << "\t0x" << (int) klartext [4 + i] << "\t0x" << (int) klartext [8 + i] << "\t0x" << (int) klartext[12 + i] << endl;
cout << endl;
}
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() {
}
void myAES::enterKlartext() {
string RED_start = "\033[22;31m";
string RED_end = "\033[0m";
string GREEN_start = "\033[22;32m";
string GREEN_end = "\033[0m";
string tmp = "";
int diff = 0;
cout << "Klartext (16 Zeichen):";
if (cin >> tmp) {
if (tmp.length() > 16) {
cerr << RED_start << "\nWerte fuer den Klartext zu groß. Trenne nach 16 Zeichen ab.\n(" << GREEN_start;
for (int i = 0; i < tmp.length(); i++) {
if (i == 16) {
cerr << RED_start << " | ";
}
cerr << tmp.at(i);
}
cout << ")" << RED_end << endl;
}
if (tmp.length() < 16) {
cerr << RED_start << "\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 << RED_end << endl;
}
for (int i = 0; i < 16; i++) {
klartext[i] = tmp[i];
}
cout << endl;
}
}
void myAES::enterSchluessel() {
string RED_start = "\033[22;31m";
string RED_end = "\033[0m";
string GREEN_start = "\033[22;32m";
string GREEN_end = "\033[0m";
string tmp = "";
int diff = 0;
cout << "Schluessel (16 Zeichen):";
if (cin >> tmp) {
if (tmp.length() > 16) {
cerr << RED_start << "\nWerte fuer den Schluessel zu groß. Trenne nach 16 Zeichen ab.\n(" << GREEN_start;
for (int i = 0; i < tmp.length(); i++) {
if (i == 16) {
cerr << RED_start << " | ";
}
cerr << tmp.at(i);
}
cout << ")" << RED_end << endl;
}
if (tmp.length() < 16) {
cerr << RED_start << "\nWert fuer den Schluessel zu klein. Fuelle mit Nullen auf.\n";
diff = 16 - tmp.length();
for (int i = 0; i < diff; i++) {
tmp.push_back('\0');
}
cout << RED_end << endl;
}
for (int i = 0; i < 16; i++) {
schluessel[i] = tmp[i];
//cout << hex << tmp[i];
}
cout << endl;
}
}
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;
}
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();
// Print-Methoden
void printSchluessel();
void printCiphertext();
void printKlartext();
private:
//unsigned int stellen;
uchar iv[16];
uchar key[16];
vector<uchar> klartext;
vector<uchar> ciphertext;
};
#endif /* MYCBC_H */
myCBC.cpp
#include "myCBC.h"
void myCBC::enterKey() {
string RED_start = "\033[22;31m";
string RED_end = "\033[0m";
string GREEN_start = "\033[22;32m";
string GREEN_end = "\033[0m";
string tmp = "";
int diff = 0;
cout << "Schluessel (16 Zeichen):";
if (cin >> tmp) {
if (tmp.length() > 16) {
cerr << RED_start << "\nWerte fuer den Schluessel zu groß. Trenne nach 16 Zeichen ab.\n(" << GREEN_start;
for (int i = 0; i < tmp.length(); i++) {
if (i == 16) {
cerr << RED_start << " | ";
}
cerr << tmp.at(i);
}
cout << ")" << RED_end << endl;
}
if (tmp.length() < 16) {
cerr << RED_start << "\nWert fuer den Schluessel zu klein. Fuelle mit Nullen auf.\n";
diff = 16 - tmp.length();
for (int i = 0; i < diff; i++) {
tmp.push_back('\0');
}
cout << RED_end << endl;
}
for (int i = 0; i < 16; i++) {
key[i] = tmp[i];
}
cout << endl;
}
}
void myCBC::enterIV() {
string RED_start = "\033[22;31m";
string RED_end = "\033[0m";
string GREEN_start = "\033[22;32m";
string GREEN_end = "\033[0m";
string tmp = "";
int diff = 0;
cout << "IV (16 Zeichen):";
if (cin >> tmp) {
if (tmp.length() > 16) {
cerr << RED_start << "\nWerte fuer den IV zu groß. Trenne nach 16 Zeichen ab.\n(" << GREEN_start;
for (int i = 0; i < tmp.length(); i++) {
if (i == 16) {
cerr << RED_start << " | ";
}
cerr << tmp.at(i);
}
cout << ")" << RED_end << endl;
}
if (tmp.length() < 16) {
cerr << RED_start << "\nWert fuer den IV zu klein. Fuelle mit Nullen auf.\n";
diff = 16 - tmp.length();
for (int i = 0; i < diff; i++) {
tmp.push_back('\0');
}
cout << RED_end << endl;
}
for (int i = 0; i < 16; i++) {
iv[i] = tmp[i];
}
cout << endl;
}
}
void myCBC::enterKlartext() {
string RED_start = "\033[22;31m";
string RED_end = "\033[0m";
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 << RED_start << "\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 << RED_end << 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]);
}
}
void myCBC::printSchluessel() {
cout << endl << "Schluessel:\n";
for (int i = 0; i < 4; i++)
cout << hex << "\t0x" << (int) key[0 + i] << "\t0x" << (int) key [4 + i] << "\t0x" << (int) key [8 + i] << "\t0x" << (int) key[12 + i] << endl;
cout << endl;
}
void myCBC::printCiphertext() {
cout << endl << "Ciphertext:\n";
for (int i = 0; i < ciphertext.size(); i++) {
cout << std::hex << " 0x" << (int) ciphertext[i];
}
}
void myCBC::printKlartext() {
cout << endl << "Klartext:\n";
for (int i = 0; i < klartext.size(); i++) {
cout << std::hex << " 0x" << (int) klartext[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];
}
//printSchluessel();
//printKlartext();
//printCiphertext();
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++) {
a1.getKlartext()[j] = a1.getKlartext()[j]^tmp_iv[j];
}
for (int j = 0; j < 16; j++) {
tmp_iv[j] = a1.getCiphertext()[j + 16 * i];
klartext.push_back(a1.getKlartext()[j]);
}
}
if (print) {
printSchluessel();
printCiphertext();
printKlartext();
}
}
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]);
}
}
if (print) {
printSchluessel();
printKlartext();
printCiphertext();
}
}
void myCBC::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 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();
// Print-Methoden
void printSchluessel();
void printCiphertext();
void printKlartext();
private:
//unsigned int stellen;
uchar key[16];
vector<uchar> klartext;
vector<uchar> ciphertext;
};
#endif /* MYECB_H */
myECB.cpp
#include "myECB.h"
void myECB::enterKey() {
string RED_start = "\033[22;31m";
string RED_end = "\033[0m";
string GREEN_start = "\033[22;32m";
string GREEN_end = "\033[0m";
string tmp = "";
int diff = 0;
cout << "Schluessel (16 Zeichen):";
if (cin >> tmp) {
if (tmp.length() > 16) {
cerr << RED_start << "\nWerte fuer den Schluessel zu groß. Trenne nach 16 Zeichen ab.\n(" << GREEN_start;
for (int i = 0; i < tmp.length(); i++) {
if (i == 16) {
cerr << RED_start << " | ";
}
cerr << tmp.at(i);
}
cout << ")" << RED_end << endl;
}
if (tmp.length() < 16) {
cerr << RED_start << "\nWert fuer den Schluessel zu klein. Fuelle mit Nullen auf.\n";
diff = 16 - tmp.length();
for (int i = 0; i < diff; i++) {
tmp.push_back('\0');
}
cout << RED_end << endl;
}
for (int i = 0; i < 16; i++) {
key[i] = tmp[i];
}
cout << endl;
}
}
void myECB::enterKlartext() {
string RED_start = "\033[22;31m";
string RED_end = "\033[0m";
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 << RED_start << "\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 << RED_end << 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 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];
}
// Klartext setzen
for (int i = 0; i < 16; i++) {
klartext.push_back(newKlartext[i]);
}
}
void myECB::printSchluessel() {
cout << endl << "Schluessel:\n";
for (int i = 0; i < 4; i++)
cout << hex << "\t0x" << (int) key[0 + i] << "\t0x" << (int) key [4 + i] << "\t0x" << (int) key [8 + i] << "\t0x" << (int) key[12 + i] << endl;
cout << endl;
}
void myECB::printCiphertext() {
cout << endl << "Ciphertext:\n";
for (int i = 0; i < ciphertext.size(); i++) {
cout << std::hex << " 0x" << (int) ciphertext[i];
}
}
void myECB::printKlartext() {
cout << endl << "Klartext:\n";
for (int i = 0; i < klartext.size(); i++) {
cout << std::hex << " 0x" << (int) klartext[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]);
}
}
if (print) {
printSchluessel();
printCiphertext();
printKlartext();
}
}
void myECB::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]);
}
}
if (print) {
printSchluessel();
printKlartext();
printCiphertext();
}
}
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() {
}
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 << RED_end << endl;
}
for (int i = 0; i < 16; i++) {
iv[i] = tmp[i];
}
cout << endl;
}
}
void myCBC::enterKlartext() {
string RED_start = "3[22;31m";
string RED_end = "3[0m";
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 << RED_start << "\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 3)
Skript-Anfang Kryptouebung2 – Seite 1 Skript-Ende Kryptouebung2 – Seite 1
main.cpp
// Präprozessor-Direktiven
#include <cstdlib>
#include <iostream>
#include <iomanip>
#include "myGUI.h"
// Using-Deklarationen
using namespace std;
int main(int argc, char** argv) {
myGUI gui;
}// main
myGUI.h
#ifndef MYGUI_H
#define MYGUI_H
#include <iostream>
#include "myCBC.h"
#include "myECB.h"
class myGUI {
public:
myGUI();
void callAES();
void callCBC();
void callECB();
bool checkAES();
bool checkCBC();
bool checkECB();
int validatedInput(unsigned int, unsigned int);
virtual ~myGUI();
private:
};
#endif /* MYGUI_H */
myGUI.cpp
#include "myGUI.h"
#include <vector>
using namespace std;
bool areEqual(vector<uchar> v1, vector<uchar> v2) {
bool tmp = false;
if (v1.size() == v2.size()) {
for (int i = 0; i < v1.size(); i++) {
if (v1[i] == v2[i]) {
tmp = true;
} else {
cout << hex << v1[i] << "!=" << v2[i] << endl;
tmp = false;
break;
}
}
}
return tmp;
}
bool areEqual(uchar* arr1, uchar* 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;
}
bool myGUI::checkCBC() {
bool returnValue = false;
//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};
vector<uchar> cipherB1;
vector<uchar> ktB;
for (int i = 0; i < 16; i++) {
ktB.push_back(klartextB1[i]);
cipherB1.push_back(ciphertextB1[i]);
}
myCBC cbcB;
cbcB.setKey(keyB);
cbcB.setIV(ivB);
cbcB.setKlartext(ktB);
cbcB.crypt(false);
// 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};
vector<uchar> cipherA1;
vector<uchar> test;
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]);
}
myCBC cbcA;
cbcA.setKey(keyA);
cbcA.setIV(ivA);
cbcA.setKlartext(test);
cbcA.crypt(false);
//Prüfung
bool isWorking = areEqual(cbcA.getCiphertext(), cipherA1) && areEqual(cbcB.getCiphertext(), cipherB1);
if (isWorking) {
returnValue = true;
} else {
returnValue = false;
}
return returnValue;
}
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};
vector<uchar> cipherB1;
vector<uchar> ktB;
for (int i = 0; i < 16; i++) {
ktB.push_back(klartext_1[i]);
cipherB1.push_back(cipher_1[i]);
}
for (int i = 0; i < 16; i++) {
ktB.push_back(klartext_2[i]);
cipherB1.push_back(cipher_2[i]);
}
for (int i = 0; i < 16; i++) {
ktB.push_back(klartext_3[i]);
cipherB1.push_back(cipher_3[i]);
}
myECB ecb;
ecb.setKey(schluessel);
ecb.setKlartext(ktB);
ecb.crypt(false);
//Prüfung
bool isWorking = areEqual(ecb.getCiphertext(), cipherB1);
if (isWorking) {
returnValue = true;
} else {
returnValue = false;
}
return returnValue;
}
bool myGUI::checkAES() {
bool returnValue = false;
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};
myAES aes1;
aes1.setKlartext(klartext_1);
aes1.setSchluessel(schluessel);
aes1.crypt(false);
myAES aes2;
aes2.setKlartext(klartext_2);
aes2.setSchluessel(schluessel);
aes2.crypt(false);
myAES aes3;
aes3.setKlartext(klartext_3);
aes3.setSchluessel(schluessel);
aes3.crypt(false);
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::callAES() {
string RED_start = "\033[22;31m";
string RED_end = "\033[0m";
myAES aes;
aes.crypt(false);
//myAES aesDecrypt;
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) Text und Schluessel aus Datei laden\n";
cout << "(4) Entschluesseln \n";
cout << "(5) Zurueck\n";
cout << "> ";
input = validatedInput(lowest, end);
if (input == 1) {
aes.crypt(true);
}
if (input == 2) {
aes.enterKlartext();
aes.enterSchluessel();
aes.crypt(true);
}
if (input == 3) {
cerr << RED_start << "Noch nicht implementiert\n" << RED_end;
}
if (input == 4) {
aes.decrypt(true);
}
if (input == 5) {
run = false;
}
if (input == -1) {
cerr << RED_start << "Ungueltige Eingabe getätigt.\nBitte nochmal eingeben.\n" << RED_end;
cout << endl;
}
}
}
void myGUI::callCBC() {
string RED_start = "\033[22;31m";
string RED_end = "\033[0m";
myCBC cbc;
cbc.crypt(true);
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) Text und Schluessel aus Datei laden\n";
cout << "(4) Text entschluesseln\n";
cout << "(5) Zurueck\n";
cout << "> ";
input = validatedInput(lowest, end);
if (input == 1) {
cbc.crypt(true);
}
if (input == 2) {
cbc.enterIV();
cbc.enterKey();
cbc.enterKlartext();
cbc.crypt(true);
}
if (input == 3) {
cerr << RED_start << "Noch nicht implementiert\n" << RED_end;
}
if (input == 4) {
cbc.decrypt(true);
}
if (input == 5) {
run = false;
}
if (input == -1) {
cerr << RED_start << "Ungueltige Eingabe getätigt.\nBitte nochmal eingeben.\n" << RED_end;
cout << endl;
}
}
}
void myGUI::callECB() {
string RED_start = "\033[22;31m";
string RED_end = "\033[0m";
myECB ecb;
ecb.crypt(false);
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) Text und Schluessel aus Datei laden\n";
cout << "(4) Text entschluesseln\n";
cout << "(5) Zurueck\n";
cout << "> ";
input = validatedInput(lowest, end);
if (input == 1) {
ecb.crypt(true);
}
if (input == 2) {
ecb.enterKey();
ecb.enterKlartext();
ecb.crypt(true);
}
if (input == 3) {
cerr << RED_start << "Noch nicht implementiert\n" << RED_end;
}
if (input == 4) {
ecb.decrypt(true);
}
if (input == 5) {
run = false;
}
if (input == -1) {
cerr << RED_start << "Ungueltige Eingabe getätigt.\nBitte nochmal eingeben.\n" << RED_end;
cout << endl;
}
}
}
int myGUI::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 {
string trash = "";
cin.clear();
std::getline(std::cin, trash);
}
return -1;
}
myGUI::myGUI() {
string RED_start = "\033[22;31m";
string RED_end = "\033[0m";
string GREEN_start = "\033[22;32m";
string GREEN_end = "\033[0m";
//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 geprüft.\n";
// AES Check
cout << "\nAES:\t\t";
if (checkAES()) {
cout << GREEN_start << "OK" << GREEN_end;
} else {
cerr << RED_start << "Fehler" << RED_end;
}
// CBC Check
cout << "\nAES mit CBC:\t";
if (checkCBC()) {
cout << GREEN_start << "OK" << GREEN_end;
} else {
cerr << RED_start << "Fehler" << RED_end;
}
// ECB Check
cout << "\nAES mit ECB:\t";
if (checkECB())
{
cout << GREEN_start << "OK" << GREEN_end;
}
else
{
cerr << RED_start << "Fehler" << RED_end;
}
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 << "> ";
input = validatedInput(lowest, end);
// Aufrufe
if (input == 1) {
cout << GREEN_start << "#### AES ####\n" << GREEN_end;
callAES();
cout << endl;
}
if (input == 2) {
cout << GREEN_start << "#### AES mit CBC ####\n" << GREEN_end;
callCBC();
cout << endl;
}
if (input == 3) {
cout << GREEN_start << "#### AES mit ECB ####\n" << GREEN_end;
callECB();
cout << endl;
}
// Fehler
if (input == -1) {
cerr << RED_start << "Ungueltige Eingabe getätigt.\nBitte nochmal eingeben.\n" << RED_end;
cout << endl;
}
// Beenden
if (input == end) {
cout << "Programm wird beendet.\n";
run = false;
cout << endl;
}
}
}
myGUI::~myGUI() {
}
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();
// AES-Methoden
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);
// Print-Methoden
void printSchluessel();
void printCiphertext();
void printKlartext();
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;
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
};
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 klartext[], int iLaenge, 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++) {
klartext[pos] = klartext[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, arrSize, carrRundenschluessel, iReihe, iSpalte, i);
}
// Ausgabe des Ciphertexts
if (output) {
printSchluessel();
printKlartext();
printCiphertext();
}
}
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);
//printRundenSchluessel(carrRundenschluessel, iReihe, iSpalte);
// "neue" Vorrunde
addRoundKey(klartext, arrSize, 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, arrSize, 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];
}
// Ausgabe des Ciphertexts
if (output) {
printSchluessel();
printCiphertext();
printKlartext();
}
}// decrypt
void myAES::printSchluessel() {
cout << endl << "Schluessel:\n";
for (int i = 0; i < 4; i++)
cout << hex << "\t0x" << (int) schluessel[0 + i] << "\t0x" << (int) schluessel [4 + i] << "\t0x" << (int) schluessel [8 + i] << "\t0x" << (int) schluessel[12 + i] << endl;
cout << endl;
}
void myAES::printCiphertext() {
cout << endl << "Ciphertext:\n";
for (int i = 0; i < 4; i++)
cout << hex << "\t0x" << (int) ciphertext[0 + i] << "\t0x" << (int) ciphertext [4 + i] << "\t0x" << (int) ciphertext [8 + i] << "\t0x" << (int) ciphertext[12 + i] << endl;
cout << endl;
}
void myAES::printKlartext() {
cout << endl << "Klartext:\n";
for (int i = 0; i < 4; i++)
cout << hex << "\t0x" << (int) klartext[0 + i] << "\t0x" << (int) klartext [4 + i] << "\t0x" << (int) klartext [8 + i] << "\t0x" << (int) klartext[12 + i] << endl;
cout << endl;
}
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() {
}
void myAES::enterKlartext() {
string RED_start = "\033[22;31m";
string RED_end = "\033[0m";
string GREEN_start = "\033[22;32m";
string GREEN_end = "\033[0m";
string tmp = "";
int diff = 0;
cout << "Klartext (16 Zeichen):";
if (cin >> tmp) {
if (tmp.length() > 16) {
cerr << RED_start << "\nWerte fuer den Klartext zu groß. Trenne nach 16 Zeichen ab.\n(" << GREEN_start;
for (int i = 0; i < tmp.length(); i++) {
if (i == 16) {
cerr << RED_start << " | ";
}
cerr << tmp.at(i);
}
cout << ")" << RED_end << endl;
}
if (tmp.length() < 16) {
cerr << RED_start << "\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 << RED_end << endl;
}
for (int i = 0; i < 16; i++) {
klartext[i] = tmp[i];
}
cout << endl;
}
}
void myAES::enterSchluessel() {
string RED_start = "\033[22;31m";
string RED_end = "\033[0m";
string GREEN_start = "\033[22;32m";
string GREEN_end = "\033[0m";
string tmp = "";
int diff = 0;
cout << "Schluessel (16 Zeichen):";
if (cin >> tmp) {
if (tmp.length() > 16) {
cerr << RED_start << "\nWerte fuer den Schluessel zu groß. Trenne nach 16 Zeichen ab.\n(" << GREEN_start;
for (int i = 0; i < tmp.length(); i++) {
if (i == 16) {
cerr << RED_start << " | ";
}
cerr << tmp.at(i);
}
cout << ")" << RED_end << endl;
}
if (tmp.length() < 16) {
cerr << RED_start << "\nWert fuer den Schluessel zu klein. Fuelle mit Nullen auf.\n";
diff = 16 - tmp.length();
for (int i = 0; i < diff; i++) {
tmp.push_back('\0');
}
cout << RED_end << endl;
}
for (int i = 0; i < 16; i++) {
schluessel[i] = tmp[i];
//cout << hex << tmp[i];
}
cout << endl;
}
}
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;
}
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();
// Print-Methoden
void printSchluessel();
void printCiphertext();
void printKlartext();
private:
//unsigned int stellen;
uchar iv[16];
uchar key[16];
vector<uchar> klartext;
vector<uchar> ciphertext;
};
#endif /* MYCBC_H */
myCBC.cpp
#include "myCBC.h"
void myCBC::enterKey() {
string RED_start = "\033[22;31m";
string RED_end = "\033[0m";
string GREEN_start = "\033[22;32m";
string GREEN_end = "\033[0m";
string tmp = "";
int diff = 0;
cout << "Schluessel (16 Zeichen):";
if (cin >> tmp) {
if (tmp.length() > 16) {
cerr << RED_start << "\nWerte fuer den Schluessel zu groß. Trenne nach 16 Zeichen ab.\n(" << GREEN_start;
for (int i = 0; i < tmp.length(); i++) {
if (i == 16) {
cerr << RED_start << " | ";
}
cerr << tmp.at(i);
}
cout << ")" << RED_end << endl;
}
if (tmp.length() < 16) {
cerr << RED_start << "\nWert fuer den Schluessel zu klein. Fuelle mit Nullen auf.\n";
diff = 16 - tmp.length();
for (int i = 0; i < diff; i++) {
tmp.push_back('\0');
}
cout << RED_end << endl;
}
for (int i = 0; i < 16; i++) {
key[i] = tmp[i];
}
cout << endl;
}
}
void myCBC::enterIV() {
string RED_start = "\033[22;31m";
string RED_end = "\033[0m";
string GREEN_start = "\033[22;32m";
string GREEN_end = "\033[0m";
string tmp = "";
int diff = 0;
cout << "IV (16 Zeichen):";
if (cin >> tmp) {
if (tmp.length() > 16) {
cerr << RED_start << "\nWerte fuer den IV zu groß. Trenne nach 16 Zeichen ab.\n(" << GREEN_start;
for (int i = 0; i < tmp.length(); i++) {
if (i == 16) {
cerr << RED_start << " | ";
}
cerr << tmp.at(i);
}
cout << ")" << RED_end << endl;
}
if (tmp.length() < 16) {
cerr << RED_start << "\nWert fuer den IV zu klein. Fuelle mit Nullen auf.\n";
diff = 16 - tmp.length();
for (int i = 0; i < diff; i++) {
tmp.push_back('\0');
}
cout << RED_end << endl;
}
for (int i = 0; i < 16; i++) {
iv[i] = tmp[i];
}
cout << endl;
}
}
void myCBC::enterKlartext() {
string RED_start = "\033[22;31m";
string RED_end = "\033[0m";
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 << RED_start << "\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 << RED_end << 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]);
}
}
void myCBC::printSchluessel() {
cout << endl << "Schluessel:\n";
for (int i = 0; i < 4; i++)
cout << hex << "\t0x" << (int) key[0 + i] << "\t0x" << (int) key [4 + i] << "\t0x" << (int) key [8 + i] << "\t0x" << (int) key[12 + i] << endl;
cout << endl;
}
void myCBC::printCiphertext() {
cout << endl << "Ciphertext:\n";
for (int i = 0; i < ciphertext.size(); i++) {
cout << std::hex << " 0x" << (int) ciphertext[i];
}
}
void myCBC::printKlartext() {
cout << endl << "Klartext:\n";
for (int i = 0; i < klartext.size(); i++) {
cout << std::hex << " 0x" << (int) klartext[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];
}
//printSchluessel();
//printKlartext();
//printCiphertext();
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++) {
a1.getKlartext()[j] = a1.getKlartext()[j]^tmp_iv[j];
}
for (int j = 0; j < 16; j++) {
tmp_iv[j] = a1.getCiphertext()[j + 16 * i];
klartext.push_back(a1.getKlartext()[j]);
}
}
if (print) {
printSchluessel();
printCiphertext();
printKlartext();
}
}
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]);
}
}
if (print) {
printSchluessel();
printKlartext();
printCiphertext();
}
}
void myCBC::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 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();
// Print-Methoden
void printSchluessel();
void printCiphertext();
void printKlartext();
private:
//unsigned int stellen;
uchar key[16];
vector<uchar> klartext;
vector<uchar> ciphertext;
};
#endif /* MYECB_H */
myECB.cpp
#include "myECB.h"
void myECB::enterKey() {
string RED_start = "\033[22;31m";
string RED_end = "\033[0m";
string GREEN_start = "\033[22;32m";
string GREEN_end = "\033[0m";
string tmp = "";
int diff = 0;
cout << "Schluessel (16 Zeichen):";
if (cin >> tmp) {
if (tmp.length() > 16) {
cerr << RED_start << "\nWerte fuer den Schluessel zu groß. Trenne nach 16 Zeichen ab.\n(" << GREEN_start;
for (int i = 0; i < tmp.length(); i++) {
if (i == 16) {
cerr << RED_start << " | ";
}
cerr << tmp.at(i);
}
cout << ")" << RED_end << endl;
}
if (tmp.length() < 16) {
cerr << RED_start << "\nWert fuer den Schluessel zu klein. Fuelle mit Nullen auf.\n";
diff = 16 - tmp.length();
for (int i = 0; i < diff; i++) {
tmp.push_back('\0');
}
cout << RED_end << endl;
}
for (int i = 0; i < 16; i++) {
key[i] = tmp[i];
}
cout << endl;
}
}
void myECB::enterKlartext() {
string RED_start = "\033[22;31m";
string RED_end = "\033[0m";
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 << RED_start << "\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 << RED_end << 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 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];
}
// Klartext setzen
for (int i = 0; i < 16; i++) {
klartext.push_back(newKlartext[i]);
}
}
void myECB::printSchluessel() {
cout << endl << "Schluessel:\n";
for (int i = 0; i < 4; i++)
cout << hex << "\t0x" << (int) key[0 + i] << "\t0x" << (int) key [4 + i] << "\t0x" << (int) key [8 + i] << "\t0x" << (int) key[12 + i] << endl;
cout << endl;
}
void myECB::printCiphertext() {
cout << endl << "Ciphertext:\n";
for (int i = 0; i < ciphertext.size(); i++) {
cout << std::hex << " 0x" << (int) ciphertext[i];
}
}
void myECB::printKlartext() {
cout << endl << "Klartext:\n";
for (int i = 0; i < klartext.size(); i++) {
cout << std::hex << " 0x" << (int) klartext[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]);
}
}
if (print) {
printSchluessel();
printCiphertext();
printKlartext();
}
}
void myECB::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]);
}
}
if (print) {
printSchluessel();
printKlartext();
printCiphertext();
}
}
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() {
}
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 << RED_end << 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]);
}
}
void myCBC::printSchluessel() {
cout << endl << "Schluessel:\n";
for (int i = 0; i < 4; i++)
cout << hex << "\t0x" << (int) key[0 + i] << "\t0x" << (int) key [4 + i] << "\t0x" << (int) key [8 + i] << "\t0x" << (int) key[12 + i] << endl;
cout << endl;
}
void myCBC::printCiphertext() {
cout << endl << "Ciphertext:\n";
for (int i = 0; i < ciphertext.size(); i++) {
cout << std::hex << " 0x" << (int) ciphertext[i];
}
}
void myCBC::printKlartext() {
cout << endl << "Klartext:\n";
for (int i = 0; i < klartext.size(); i++) {
cout << std::hex << " 0x" << (int) klartext[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];
}
//printSchluessel();
//printKlartext();
//printCiphertext();
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++) {
a1.getKlartext()[j] = a1.getKlartext()[j]^tmp_iv[j];
}
for (int j = 0; j < 16; j++) {
tmp_iv[j] = a1.getCiphertext()[j + 16 * i];
klartext.push_back(a1.getKlartext()[j]);
}
}
if (print) {
printSchluessel();
printCiphertext();
printKlartext();
}
}
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]);
}
}
if (print) {
printSchluessel();
printKlartext();
printCiphertext();
}
}
void myCBC::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 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();
// Print-Methoden
void printSchluessel();
void printCiphertext();
void printKlartext();
private:
//unsigned int stellen;
uchar key[16];
vector<uchar> klartext;
vector<uchar> ciphertext;
};
#endif /* MYECB_H */
myECB.cpp
#include "myECB.h"
void myECB::enterKey() {
string RED_start = "3[22;31m";
string RED_end = "3[0m";
string GREEN_start = "3[22;32m";
string GREEN_end = "3[0m";
string tmp = "";
int diff = 0;
cout << "Schluessel (16 Zeichen):";
if (cin >> tmp) {
if (tmp.length() > 16) {
cerr << RED_start << "\nWerte fuer den Schluessel zu groß. Trenne nach 16 Zeichen ab.\n(" << GREEN_start;
for (int i = 0; i < tmp.length(); i++) {
if (i == 16) {
cerr << RED_start << " | ";
}
cerr << tmp.at(i);
}
cout << ")" << RED_end << endl;
}
if (tmp.length() < 16) {
cerr << RED_start << "\nWert fuer den Schluessel 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 3)
Skript-Anfang Kryptouebung2 – Seite 1 Skript-Ende Kryptouebung2 – Seite 1
main.cpp
// Präprozessor-Direktiven
#include <cstdlib>
#include <iostream>
#include <iomanip>
#include "myGUI.h"
// Using-Deklarationen
using namespace std;
int main(int argc, char** argv) {
myGUI gui;
}// main
myGUI.h
#ifndef MYGUI_H
#define MYGUI_H
#include <iostream>
#include "myCBC.h"
#include "myECB.h"
class myGUI {
public:
myGUI();
void callAES();
void callCBC();
void callECB();
bool checkAES();
bool checkCBC();
bool checkECB();
int validatedInput(unsigned int, unsigned int);
virtual ~myGUI();
private:
};
#endif /* MYGUI_H */
myGUI.cpp
#include "myGUI.h"
#include <vector>
using namespace std;
bool areEqual(vector<uchar> v1, vector<uchar> v2) {
bool tmp = false;
if (v1.size() == v2.size()) {
for (int i = 0; i < v1.size(); i++) {
if (v1[i] == v2[i]) {
tmp = true;
} else {
cout << hex << v1[i] << "!=" << v2[i] << endl;
tmp = false;
break;
}
}
}
return tmp;
}
bool areEqual(uchar* arr1, uchar* 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;
}
bool myGUI::checkCBC() {
bool returnValue = false;
//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};
vector<uchar> cipherB1;
vector<uchar> ktB;
for (int i = 0; i < 16; i++) {
ktB.push_back(klartextB1[i]);
cipherB1.push_back(ciphertextB1[i]);
}
myCBC cbcB;
cbcB.setKey(keyB);
cbcB.setIV(ivB);
cbcB.setKlartext(ktB);
cbcB.crypt(false);
// 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};
vector<uchar> cipherA1;
vector<uchar> test;
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]);
}
myCBC cbcA;
cbcA.setKey(keyA);
cbcA.setIV(ivA);
cbcA.setKlartext(test);
cbcA.crypt(false);
//Prüfung
bool isWorking = areEqual(cbcA.getCiphertext(), cipherA1) && areEqual(cbcB.getCiphertext(), cipherB1);
if (isWorking) {
returnValue = true;
} else {
returnValue = false;
}
return returnValue;
}
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};
vector<uchar> cipherB1;
vector<uchar> ktB;
for (int i = 0; i < 16; i++) {
ktB.push_back(klartext_1[i]);
cipherB1.push_back(cipher_1[i]);
}
for (int i = 0; i < 16; i++) {
ktB.push_back(klartext_2[i]);
cipherB1.push_back(cipher_2[i]);
}
for (int i = 0; i < 16; i++) {
ktB.push_back(klartext_3[i]);
cipherB1.push_back(cipher_3[i]);
}
myECB ecb;
ecb.setKey(schluessel);
ecb.setKlartext(ktB);
ecb.crypt(false);
//Prüfung
bool isWorking = areEqual(ecb.getCiphertext(), cipherB1);
if (isWorking) {
returnValue = true;
} else {
returnValue = false;
}
return returnValue;
}
bool myGUI::checkAES() {
bool returnValue = false;
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};
myAES aes1;
aes1.setKlartext(klartext_1);
aes1.setSchluessel(schluessel);
aes1.crypt(false);
myAES aes2;
aes2.setKlartext(klartext_2);
aes2.setSchluessel(schluessel);
aes2.crypt(false);
myAES aes3;
aes3.setKlartext(klartext_3);
aes3.setSchluessel(schluessel);
aes3.crypt(false);
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::callAES() {
string RED_start = "\033[22;31m";
string RED_end = "\033[0m";
myAES aes;
aes.crypt(false);
//myAES aesDecrypt;
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) Text und Schluessel aus Datei laden\n";
cout << "(4) Entschluesseln \n";
cout << "(5) Zurueck\n";
cout << "> ";
input = validatedInput(lowest, end);
if (input == 1) {
aes.crypt(true);
}
if (input == 2) {
aes.enterKlartext();
aes.enterSchluessel();
aes.crypt(true);
}
if (input == 3) {
cerr << RED_start << "Noch nicht implementiert\n" << RED_end;
}
if (input == 4) {
aes.decrypt(true);
}
if (input == 5) {
run = false;
}
if (input == -1) {
cerr << RED_start << "Ungueltige Eingabe getätigt.\nBitte nochmal eingeben.\n" << RED_end;
cout << endl;
}
}
}
void myGUI::callCBC() {
string RED_start = "\033[22;31m";
string RED_end = "\033[0m";
myCBC cbc;
cbc.crypt(true);
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) Text und Schluessel aus Datei laden\n";
cout << "(4) Text entschluesseln\n";
cout << "(5) Zurueck\n";
cout << "> ";
input = validatedInput(lowest, end);
if (input == 1) {
cbc.crypt(true);
}
if (input == 2) {
cbc.enterIV();
cbc.enterKey();
cbc.enterKlartext();
cbc.crypt(true);
}
if (input == 3) {
cerr << RED_start << "Noch nicht implementiert\n" << RED_end;
}
if (input == 4) {
cbc.decrypt(true);
}
if (input == 5) {
run = false;
}
if (input == -1) {
cerr << RED_start << "Ungueltige Eingabe getätigt.\nBitte nochmal eingeben.\n" << RED_end;
cout << endl;
}
}
}
void myGUI::callECB() {
string RED_start = "\033[22;31m";
string RED_end = "\033[0m";
myECB ecb;
ecb.crypt(false);
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) Text und Schluessel aus Datei laden\n";
cout << "(4) Text entschluesseln\n";
cout << "(5) Zurueck\n";
cout << "> ";
input = validatedInput(lowest, end);
if (input == 1) {
ecb.crypt(true);
}
if (input == 2) {
ecb.enterKey();
ecb.enterKlartext();
ecb.crypt(true);
}
if (input == 3) {
cerr << RED_start << "Noch nicht implementiert\n" << RED_end;
}
if (input == 4) {
ecb.decrypt(true);
}
if (input == 5) {
run = false;
}
if (input == -1) {
cerr << RED_start << "Ungueltige Eingabe getätigt.\nBitte nochmal eingeben.\n" << RED_end;
cout << endl;
}
}
}
int myGUI::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 {
string trash = "";
cin.clear();
std::getline(std::cin, trash);
}
return -1;
}
myGUI::myGUI() {
string RED_start = "\033[22;31m";
string RED_end = "\033[0m";
string GREEN_start = "\033[22;32m";
string GREEN_end = "\033[0m";
//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 geprüft.\n";
// AES Check
cout << "\nAES:\t\t";
if (checkAES()) {
cout << GREEN_start << "OK" << GREEN_end;
} else {
cerr << RED_start << "Fehler" << RED_end;
}
// CBC Check
cout << "\nAES mit CBC:\t";
if (checkCBC()) {
cout << GREEN_start << "OK" << GREEN_end;
} else {
cerr << RED_start << "Fehler" << RED_end;
}
// ECB Check
cout << "\nAES mit ECB:\t";
if (checkECB())
{
cout << GREEN_start << "OK" << GREEN_end;
}
else
{
cerr << RED_start << "Fehler" << RED_end;
}
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 << "> ";
input = validatedInput(lowest, end);
// Aufrufe
if (input == 1) {
cout << GREEN_start << "#### AES ####\n" << GREEN_end;
callAES();
cout << endl;
}
if (input == 2) {
cout << GREEN_start << "#### AES mit CBC ####\n" << GREEN_end;
callCBC();
cout << endl;
}
if (input == 3) {
cout << GREEN_start << "#### AES mit ECB ####\n" << GREEN_end;
callECB();
cout << endl;
}
// Fehler
if (input == -1) {
cerr << RED_start << "Ungueltige Eingabe getätigt.\nBitte nochmal eingeben.\n" << RED_end;
cout << endl;
}
// Beenden
if (input == end) {
cout << "Programm wird beendet.\n";
run = false;
cout << endl;
}
}
}
myGUI::~myGUI() {
}
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();
// AES-Methoden
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);
// Print-Methoden
void printSchluessel();
void printCiphertext();
void printKlartext();
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;
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
};
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 klartext[], int iLaenge, 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++) {
klartext[pos] = klartext[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, arrSize, carrRundenschluessel, iReihe, iSpalte, i);
}
// Ausgabe des Ciphertexts
if (output) {
printSchluessel();
printKlartext();
printCiphertext();
}
}
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);
//printRundenSchluessel(carrRundenschluessel, iReihe, iSpalte);
// "neue" Vorrunde
addRoundKey(klartext, arrSize, 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, arrSize, 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];
}
// Ausgabe des Ciphertexts
if (output) {
printSchluessel();
printCiphertext();
printKlartext();
}
}// decrypt
void myAES::printSchluessel() {
cout << endl << "Schluessel:\n";
for (int i = 0; i < 4; i++)
cout << hex << "\t0x" << (int) schluessel[0 + i] << "\t0x" << (int) schluessel [4 + i] << "\t0x" << (int) schluessel [8 + i] << "\t0x" << (int) schluessel[12 + i] << endl;
cout << endl;
}
void myAES::printCiphertext() {
cout << endl << "Ciphertext:\n";
for (int i = 0; i < 4; i++)
cout << hex << "\t0x" << (int) ciphertext[0 + i] << "\t0x" << (int) ciphertext [4 + i] << "\t0x" << (int) ciphertext [8 + i] << "\t0x" << (int) ciphertext[12 + i] << endl;
cout << endl;
}
void myAES::printKlartext() {
cout << endl << "Klartext:\n";
for (int i = 0; i < 4; i++)
cout << hex << "\t0x" << (int) klartext[0 + i] << "\t0x" << (int) klartext [4 + i] << "\t0x" << (int) klartext [8 + i] << "\t0x" << (int) klartext[12 + i] << endl;
cout << endl;
}
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() {
}
void myAES::enterKlartext() {
string RED_start = "\033[22;31m";
string RED_end = "\033[0m";
string GREEN_start = "\033[22;32m";
string GREEN_end = "\033[0m";
string tmp = "";
int diff = 0;
cout << "Klartext (16 Zeichen):";
if (cin >> tmp) {
if (tmp.length() > 16) {
cerr << RED_start << "\nWerte fuer den Klartext zu groß. Trenne nach 16 Zeichen ab.\n(" << GREEN_start;
for (int i = 0; i < tmp.length(); i++) {
if (i == 16) {
cerr << RED_start << " | ";
}
cerr << tmp.at(i);
}
cout << ")" << RED_end << endl;
}
if (tmp.length() < 16) {
cerr << RED_start << "\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 << RED_end << endl;
}
for (int i = 0; i < 16; i++) {
klartext[i] = tmp[i];
}
cout << endl;
}
}
void myAES::enterSchluessel() {
string RED_start = "\033[22;31m";
string RED_end = "\033[0m";
string GREEN_start = "\033[22;32m";
string GREEN_end = "\033[0m";
string tmp = "";
int diff = 0;
cout << "Schluessel (16 Zeichen):";
if (cin >> tmp) {
if (tmp.length() > 16) {
cerr << RED_start << "\nWerte fuer den Schluessel zu groß. Trenne nach 16 Zeichen ab.\n(" << GREEN_start;
for (int i = 0; i < tmp.length(); i++) {
if (i == 16) {
cerr << RED_start << " | ";
}
cerr << tmp.at(i);
}
cout << ")" << RED_end << endl;
}
if (tmp.length() < 16) {
cerr << RED_start << "\nWert fuer den Schluessel zu klein. Fuelle mit Nullen auf.\n";
diff = 16 - tmp.length();
for (int i = 0; i < diff; i++) {
tmp.push_back('\0');
}
cout << RED_end << endl;
}
for (int i = 0; i < 16; i++) {
schluessel[i] = tmp[i];
//cout << hex << tmp[i];
}
cout << endl;
}
}
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;
}
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();
// Print-Methoden
void printSchluessel();
void printCiphertext();
void printKlartext();
private:
//unsigned int stellen;
uchar iv[16];
uchar key[16];
vector<uchar> klartext;
vector<uchar> ciphertext;
};
#endif /* MYCBC_H */
myCBC.cpp
#include "myCBC.h"
void myCBC::enterKey() {
string RED_start = "\033[22;31m";
string RED_end = "\033[0m";
string GREEN_start = "\033[22;32m";
string GREEN_end = "\033[0m";
string tmp = "";
int diff = 0;
cout << "Schluessel (16 Zeichen):";
if (cin >> tmp) {
if (tmp.length() > 16) {
cerr << RED_start << "\nWerte fuer den Schluessel zu groß. Trenne nach 16 Zeichen ab.\n(" << GREEN_start;
for (int i = 0; i < tmp.length(); i++) {
if (i == 16) {
cerr << RED_start << " | ";
}
cerr << tmp.at(i);
}
cout << ")" << RED_end << endl;
}
if (tmp.length() < 16) {
cerr << RED_start << "\nWert fuer den Schluessel zu klein. Fuelle mit Nullen auf.\n";
diff = 16 - tmp.length();
for (int i = 0; i < diff; i++) {
tmp.push_back('\0');
}
cout << RED_end << endl;
}
for (int i = 0; i < 16; i++) {
key[i] = tmp[i];
}
cout << endl;
}
}
void myCBC::enterIV() {
string RED_start = "\033[22;31m";
string RED_end = "\033[0m";
string GREEN_start = "\033[22;32m";
string GREEN_end = "\033[0m";
string tmp = "";
int diff = 0;
cout << "IV (16 Zeichen):";
if (cin >> tmp) {
if (tmp.length() > 16) {
cerr << RED_start << "\nWerte fuer den IV zu groß. Trenne nach 16 Zeichen ab.\n(" << GREEN_start;
for (int i = 0; i < tmp.length(); i++) {
if (i == 16) {
cerr << RED_start << " | ";
}
cerr << tmp.at(i);
}
cout << ")" << RED_end << endl;
}
if (tmp.length() < 16) {
cerr << RED_start << "\nWert fuer den IV zu klein. Fuelle mit Nullen auf.\n";
diff = 16 - tmp.length();
for (int i = 0; i < diff; i++) {
tmp.push_back('\0');
}
cout << RED_end << endl;
}
for (int i = 0; i < 16; i++) {
iv[i] = tmp[i];
}
cout << endl;
}
}
void myCBC::enterKlartext() {
string RED_start = "\033[22;31m";
string RED_end = "\033[0m";
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 << RED_start << "\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 << RED_end << 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]);
}
}
void myCBC::printSchluessel() {
cout << endl << "Schluessel:\n";
for (int i = 0; i < 4; i++)
cout << hex << "\t0x" << (int) key[0 + i] << "\t0x" << (int) key [4 + i] << "\t0x" << (int) key [8 + i] << "\t0x" << (int) key[12 + i] << endl;
cout << endl;
}
void myCBC::printCiphertext() {
cout << endl << "Ciphertext:\n";
for (int i = 0; i < ciphertext.size(); i++) {
cout << std::hex << " 0x" << (int) ciphertext[i];
}
}
void myCBC::printKlartext() {
cout << endl << "Klartext:\n";
for (int i = 0; i < klartext.size(); i++) {
cout << std::hex << " 0x" << (int) klartext[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];
}
//printSchluessel();
//printKlartext();
//printCiphertext();
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++) {
a1.getKlartext()[j] = a1.getKlartext()[j]^tmp_iv[j];
}
for (int j = 0; j < 16; j++) {
tmp_iv[j] = a1.getCiphertext()[j + 16 * i];
klartext.push_back(a1.getKlartext()[j]);
}
}
if (print) {
printSchluessel();
printCiphertext();
printKlartext();
}
}
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]);
}
}
if (print) {
printSchluessel();
printKlartext();
printCiphertext();
}
}
void myCBC::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 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();
// Print-Methoden
void printSchluessel();
void printCiphertext();
void printKlartext();
private:
//unsigned int stellen;
uchar key[16];
vector<uchar> klartext;
vector<uchar> ciphertext;
};
#endif /* MYECB_H */
myECB.cpp
#include "myECB.h"
void myECB::enterKey() {
string RED_start = "\033[22;31m";
string RED_end = "\033[0m";
string GREEN_start = "\033[22;32m";
string GREEN_end = "\033[0m";
string tmp = "";
int diff = 0;
cout << "Schluessel (16 Zeichen):";
if (cin >> tmp) {
if (tmp.length() > 16) {
cerr << RED_start << "\nWerte fuer den Schluessel zu groß. Trenne nach 16 Zeichen ab.\n(" << GREEN_start;
for (int i = 0; i < tmp.length(); i++) {
if (i == 16) {
cerr << RED_start << " | ";
}
cerr << tmp.at(i);
}
cout << ")" << RED_end << endl;
}
if (tmp.length() < 16) {
cerr << RED_start << "\nWert fuer den Schluessel zu klein. Fuelle mit Nullen auf.\n";
diff = 16 - tmp.length();
for (int i = 0; i < diff; i++) {
tmp.push_back('\0');
}
cout << RED_end << endl;
}
for (int i = 0; i < 16; i++) {
key[i] = tmp[i];
}
cout << endl;
}
}
void myECB::enterKlartext() {
string RED_start = "\033[22;31m";
string RED_end = "\033[0m";
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 << RED_start << "\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 << RED_end << 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 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];
}
// Klartext setzen
for (int i = 0; i < 16; i++) {
klartext.push_back(newKlartext[i]);
}
}
void myECB::printSchluessel() {
cout << endl << "Schluessel:\n";
for (int i = 0; i < 4; i++)
cout << hex << "\t0x" << (int) key[0 + i] << "\t0x" << (int) key [4 + i] << "\t0x" << (int) key [8 + i] << "\t0x" << (int) key[12 + i] << endl;
cout << endl;
}
void myECB::printCiphertext() {
cout << endl << "Ciphertext:\n";
for (int i = 0; i < ciphertext.size(); i++) {
cout << std::hex << " 0x" << (int) ciphertext[i];
}
}
void myECB::printKlartext() {
cout << endl << "Klartext:\n";
for (int i = 0; i < klartext.size(); i++) {
cout << std::hex << " 0x" << (int) klartext[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]);
}
}
if (print) {
printSchluessel();
printCiphertext();
printKlartext();
}
}
void myECB::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]);
}
}
if (print) {
printSchluessel();
printKlartext();
printCiphertext();
}
}
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() {
}
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 << RED_end << endl;
}
for (int i = 0; i < 16; i++) {
key[i] = tmp[i];
}
cout << endl;
}
}
void myECB::enterKlartext() {
string RED_start = "3[22;31m";
string RED_end = "3[0m";
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 << RED_start << "\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 3)
Skript-Anfang Kryptouebung2 – Seite 1 Skript-Ende Kryptouebung2 – Seite 1
main.cpp
// Präprozessor-Direktiven
#include <cstdlib>
#include <iostream>
#include <iomanip>
#include "myGUI.h"
// Using-Deklarationen
using namespace std;
int main(int argc, char** argv) {
myGUI gui;
}// main
myGUI.h
#ifndef MYGUI_H
#define MYGUI_H
#include <iostream>
#include "myCBC.h"
#include "myECB.h"
class myGUI {
public:
myGUI();
void callAES();
void callCBC();
void callECB();
bool checkAES();
bool checkCBC();
bool checkECB();
int validatedInput(unsigned int, unsigned int);
virtual ~myGUI();
private:
};
#endif /* MYGUI_H */
myGUI.cpp
#include "myGUI.h"
#include <vector>
using namespace std;
bool areEqual(vector<uchar> v1, vector<uchar> v2) {
bool tmp = false;
if (v1.size() == v2.size()) {
for (int i = 0; i < v1.size(); i++) {
if (v1[i] == v2[i]) {
tmp = true;
} else {
cout << hex << v1[i] << "!=" << v2[i] << endl;
tmp = false;
break;
}
}
}
return tmp;
}
bool areEqual(uchar* arr1, uchar* 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;
}
bool myGUI::checkCBC() {
bool returnValue = false;
//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};
vector<uchar> cipherB1;
vector<uchar> ktB;
for (int i = 0; i < 16; i++) {
ktB.push_back(klartextB1[i]);
cipherB1.push_back(ciphertextB1[i]);
}
myCBC cbcB;
cbcB.setKey(keyB);
cbcB.setIV(ivB);
cbcB.setKlartext(ktB);
cbcB.crypt(false);
// 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};
vector<uchar> cipherA1;
vector<uchar> test;
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]);
}
myCBC cbcA;
cbcA.setKey(keyA);
cbcA.setIV(ivA);
cbcA.setKlartext(test);
cbcA.crypt(false);
//Prüfung
bool isWorking = areEqual(cbcA.getCiphertext(), cipherA1) && areEqual(cbcB.getCiphertext(), cipherB1);
if (isWorking) {
returnValue = true;
} else {
returnValue = false;
}
return returnValue;
}
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};
vector<uchar> cipherB1;
vector<uchar> ktB;
for (int i = 0; i < 16; i++) {
ktB.push_back(klartext_1[i]);
cipherB1.push_back(cipher_1[i]);
}
for (int i = 0; i < 16; i++) {
ktB.push_back(klartext_2[i]);
cipherB1.push_back(cipher_2[i]);
}
for (int i = 0; i < 16; i++) {
ktB.push_back(klartext_3[i]);
cipherB1.push_back(cipher_3[i]);
}
myECB ecb;
ecb.setKey(schluessel);
ecb.setKlartext(ktB);
ecb.crypt(false);
//Prüfung
bool isWorking = areEqual(ecb.getCiphertext(), cipherB1);
if (isWorking) {
returnValue = true;
} else {
returnValue = false;
}
return returnValue;
}
bool myGUI::checkAES() {
bool returnValue = false;
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};
myAES aes1;
aes1.setKlartext(klartext_1);
aes1.setSchluessel(schluessel);
aes1.crypt(false);
myAES aes2;
aes2.setKlartext(klartext_2);
aes2.setSchluessel(schluessel);
aes2.crypt(false);
myAES aes3;
aes3.setKlartext(klartext_3);
aes3.setSchluessel(schluessel);
aes3.crypt(false);
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::callAES() {
string RED_start = "\033[22;31m";
string RED_end = "\033[0m";
myAES aes;
aes.crypt(false);
//myAES aesDecrypt;
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) Text und Schluessel aus Datei laden\n";
cout << "(4) Entschluesseln \n";
cout << "(5) Zurueck\n";
cout << "> ";
input = validatedInput(lowest, end);
if (input == 1) {
aes.crypt(true);
}
if (input == 2) {
aes.enterKlartext();
aes.enterSchluessel();
aes.crypt(true);
}
if (input == 3) {
cerr << RED_start << "Noch nicht implementiert\n" << RED_end;
}
if (input == 4) {
aes.decrypt(true);
}
if (input == 5) {
run = false;
}
if (input == -1) {
cerr << RED_start << "Ungueltige Eingabe getätigt.\nBitte nochmal eingeben.\n" << RED_end;
cout << endl;
}
}
}
void myGUI::callCBC() {
string RED_start = "\033[22;31m";
string RED_end = "\033[0m";
myCBC cbc;
cbc.crypt(true);
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) Text und Schluessel aus Datei laden\n";
cout << "(4) Text entschluesseln\n";
cout << "(5) Zurueck\n";
cout << "> ";
input = validatedInput(lowest, end);
if (input == 1) {
cbc.crypt(true);
}
if (input == 2) {
cbc.enterIV();
cbc.enterKey();
cbc.enterKlartext();
cbc.crypt(true);
}
if (input == 3) {
cerr << RED_start << "Noch nicht implementiert\n" << RED_end;
}
if (input == 4) {
cbc.decrypt(true);
}
if (input == 5) {
run = false;
}
if (input == -1) {
cerr << RED_start << "Ungueltige Eingabe getätigt.\nBitte nochmal eingeben.\n" << RED_end;
cout << endl;
}
}
}
void myGUI::callECB() {
string RED_start = "\033[22;31m";
string RED_end = "\033[0m";
myECB ecb;
ecb.crypt(false);
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) Text und Schluessel aus Datei laden\n";
cout << "(4) Text entschluesseln\n";
cout << "(5) Zurueck\n";
cout << "> ";
input = validatedInput(lowest, end);
if (input == 1) {
ecb.crypt(true);
}
if (input == 2) {
ecb.enterKey();
ecb.enterKlartext();
ecb.crypt(true);
}
if (input == 3) {
cerr << RED_start << "Noch nicht implementiert\n" << RED_end;
}
if (input == 4) {
ecb.decrypt(true);
}
if (input == 5) {
run = false;
}
if (input == -1) {
cerr << RED_start << "Ungueltige Eingabe getätigt.\nBitte nochmal eingeben.\n" << RED_end;
cout << endl;
}
}
}
int myGUI::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 {
string trash = "";
cin.clear();
std::getline(std::cin, trash);
}
return -1;
}
myGUI::myGUI() {
string RED_start = "\033[22;31m";
string RED_end = "\033[0m";
string GREEN_start = "\033[22;32m";
string GREEN_end = "\033[0m";
//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 geprüft.\n";
// AES Check
cout << "\nAES:\t\t";
if (checkAES()) {
cout << GREEN_start << "OK" << GREEN_end;
} else {
cerr << RED_start << "Fehler" << RED_end;
}
// CBC Check
cout << "\nAES mit CBC:\t";
if (checkCBC()) {
cout << GREEN_start << "OK" << GREEN_end;
} else {
cerr << RED_start << "Fehler" << RED_end;
}
// ECB Check
cout << "\nAES mit ECB:\t";
if (checkECB())
{
cout << GREEN_start << "OK" << GREEN_end;
}
else
{
cerr << RED_start << "Fehler" << RED_end;
}
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 << "> ";
input = validatedInput(lowest, end);
// Aufrufe
if (input == 1) {
cout << GREEN_start << "#### AES ####\n" << GREEN_end;
callAES();
cout << endl;
}
if (input == 2) {
cout << GREEN_start << "#### AES mit CBC ####\n" << GREEN_end;
callCBC();
cout << endl;
}
if (input == 3) {
cout << GREEN_start << "#### AES mit ECB ####\n" << GREEN_end;
callECB();
cout << endl;
}
// Fehler
if (input == -1) {
cerr << RED_start << "Ungueltige Eingabe getätigt.\nBitte nochmal eingeben.\n" << RED_end;
cout << endl;
}
// Beenden
if (input == end) {
cout << "Programm wird beendet.\n";
run = false;
cout << endl;
}
}
}
myGUI::~myGUI() {
}
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();
// AES-Methoden
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);
// Print-Methoden
void printSchluessel();
void printCiphertext();
void printKlartext();
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;
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
};
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 klartext[], int iLaenge, 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++) {
klartext[pos] = klartext[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, arrSize, carrRundenschluessel, iReihe, iSpalte, i);
}
// Ausgabe des Ciphertexts
if (output) {
printSchluessel();
printKlartext();
printCiphertext();
}
}
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);
//printRundenSchluessel(carrRundenschluessel, iReihe, iSpalte);
// "neue" Vorrunde
addRoundKey(klartext, arrSize, 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, arrSize, 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];
}
// Ausgabe des Ciphertexts
if (output) {
printSchluessel();
printCiphertext();
printKlartext();
}
}// decrypt
void myAES::printSchluessel() {
cout << endl << "Schluessel:\n";
for (int i = 0; i < 4; i++)
cout << hex << "\t0x" << (int) schluessel[0 + i] << "\t0x" << (int) schluessel [4 + i] << "\t0x" << (int) schluessel [8 + i] << "\t0x" << (int) schluessel[12 + i] << endl;
cout << endl;
}
void myAES::printCiphertext() {
cout << endl << "Ciphertext:\n";
for (int i = 0; i < 4; i++)
cout << hex << "\t0x" << (int) ciphertext[0 + i] << "\t0x" << (int) ciphertext [4 + i] << "\t0x" << (int) ciphertext [8 + i] << "\t0x" << (int) ciphertext[12 + i] << endl;
cout << endl;
}
void myAES::printKlartext() {
cout << endl << "Klartext:\n";
for (int i = 0; i < 4; i++)
cout << hex << "\t0x" << (int) klartext[0 + i] << "\t0x" << (int) klartext [4 + i] << "\t0x" << (int) klartext [8 + i] << "\t0x" << (int) klartext[12 + i] << endl;
cout << endl;
}
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() {
}
void myAES::enterKlartext() {
string RED_start = "\033[22;31m";
string RED_end = "\033[0m";
string GREEN_start = "\033[22;32m";
string GREEN_end = "\033[0m";
string tmp = "";
int diff = 0;
cout << "Klartext (16 Zeichen):";
if (cin >> tmp) {
if (tmp.length() > 16) {
cerr << RED_start << "\nWerte fuer den Klartext zu groß. Trenne nach 16 Zeichen ab.\n(" << GREEN_start;
for (int i = 0; i < tmp.length(); i++) {
if (i == 16) {
cerr << RED_start << " | ";
}
cerr << tmp.at(i);
}
cout << ")" << RED_end << endl;
}
if (tmp.length() < 16) {
cerr << RED_start << "\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 << RED_end << endl;
}
for (int i = 0; i < 16; i++) {
klartext[i] = tmp[i];
}
cout << endl;
}
}
void myAES::enterSchluessel() {
string RED_start = "\033[22;31m";
string RED_end = "\033[0m";
string GREEN_start = "\033[22;32m";
string GREEN_end = "\033[0m";
string tmp = "";
int diff = 0;
cout << "Schluessel (16 Zeichen):";
if (cin >> tmp) {
if (tmp.length() > 16) {
cerr << RED_start << "\nWerte fuer den Schluessel zu groß. Trenne nach 16 Zeichen ab.\n(" << GREEN_start;
for (int i = 0; i < tmp.length(); i++) {
if (i == 16) {
cerr << RED_start << " | ";
}
cerr << tmp.at(i);
}
cout << ")" << RED_end << endl;
}
if (tmp.length() < 16) {
cerr << RED_start << "\nWert fuer den Schluessel zu klein. Fuelle mit Nullen auf.\n";
diff = 16 - tmp.length();
for (int i = 0; i < diff; i++) {
tmp.push_back('\0');
}
cout << RED_end << endl;
}
for (int i = 0; i < 16; i++) {
schluessel[i] = tmp[i];
//cout << hex << tmp[i];
}
cout << endl;
}
}
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;
}
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();
// Print-Methoden
void printSchluessel();
void printCiphertext();
void printKlartext();
private:
//unsigned int stellen;
uchar iv[16];
uchar key[16];
vector<uchar> klartext;
vector<uchar> ciphertext;
};
#endif /* MYCBC_H */
myCBC.cpp
#include "myCBC.h"
void myCBC::enterKey() {
string RED_start = "\033[22;31m";
string RED_end = "\033[0m";
string GREEN_start = "\033[22;32m";
string GREEN_end = "\033[0m";
string tmp = "";
int diff = 0;
cout << "Schluessel (16 Zeichen):";
if (cin >> tmp) {
if (tmp.length() > 16) {
cerr << RED_start << "\nWerte fuer den Schluessel zu groß. Trenne nach 16 Zeichen ab.\n(" << GREEN_start;
for (int i = 0; i < tmp.length(); i++) {
if (i == 16) {
cerr << RED_start << " | ";
}
cerr << tmp.at(i);
}
cout << ")" << RED_end << endl;
}
if (tmp.length() < 16) {
cerr << RED_start << "\nWert fuer den Schluessel zu klein. Fuelle mit Nullen auf.\n";
diff = 16 - tmp.length();
for (int i = 0; i < diff; i++) {
tmp.push_back('\0');
}
cout << RED_end << endl;
}
for (int i = 0; i < 16; i++) {
key[i] = tmp[i];
}
cout << endl;
}
}
void myCBC::enterIV() {
string RED_start = "\033[22;31m";
string RED_end = "\033[0m";
string GREEN_start = "\033[22;32m";
string GREEN_end = "\033[0m";
string tmp = "";
int diff = 0;
cout << "IV (16 Zeichen):";
if (cin >> tmp) {
if (tmp.length() > 16) {
cerr << RED_start << "\nWerte fuer den IV zu groß. Trenne nach 16 Zeichen ab.\n(" << GREEN_start;
for (int i = 0; i < tmp.length(); i++) {
if (i == 16) {
cerr << RED_start << " | ";
}
cerr << tmp.at(i);
}
cout << ")" << RED_end << endl;
}
if (tmp.length() < 16) {
cerr << RED_start << "\nWert fuer den IV zu klein. Fuelle mit Nullen auf.\n";
diff = 16 - tmp.length();
for (int i = 0; i < diff; i++) {
tmp.push_back('\0');
}
cout << RED_end << endl;
}
for (int i = 0; i < 16; i++) {
iv[i] = tmp[i];
}
cout << endl;
}
}
void myCBC::enterKlartext() {
string RED_start = "\033[22;31m";
string RED_end = "\033[0m";
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 << RED_start << "\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 << RED_end << 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]);
}
}
void myCBC::printSchluessel() {
cout << endl << "Schluessel:\n";
for (int i = 0; i < 4; i++)
cout << hex << "\t0x" << (int) key[0 + i] << "\t0x" << (int) key [4 + i] << "\t0x" << (int) key [8 + i] << "\t0x" << (int) key[12 + i] << endl;
cout << endl;
}
void myCBC::printCiphertext() {
cout << endl << "Ciphertext:\n";
for (int i = 0; i < ciphertext.size(); i++) {
cout << std::hex << " 0x" << (int) ciphertext[i];
}
}
void myCBC::printKlartext() {
cout << endl << "Klartext:\n";
for (int i = 0; i < klartext.size(); i++) {
cout << std::hex << " 0x" << (int) klartext[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];
}
//printSchluessel();
//printKlartext();
//printCiphertext();
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++) {
a1.getKlartext()[j] = a1.getKlartext()[j]^tmp_iv[j];
}
for (int j = 0; j < 16; j++) {
tmp_iv[j] = a1.getCiphertext()[j + 16 * i];
klartext.push_back(a1.getKlartext()[j]);
}
}
if (print) {
printSchluessel();
printCiphertext();
printKlartext();
}
}
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]);
}
}
if (print) {
printSchluessel();
printKlartext();
printCiphertext();
}
}
void myCBC::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 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();
// Print-Methoden
void printSchluessel();
void printCiphertext();
void printKlartext();
private:
//unsigned int stellen;
uchar key[16];
vector<uchar> klartext;
vector<uchar> ciphertext;
};
#endif /* MYECB_H */
myECB.cpp
#include "myECB.h"
void myECB::enterKey() {
string RED_start = "\033[22;31m";
string RED_end = "\033[0m";
string GREEN_start = "\033[22;32m";
string GREEN_end = "\033[0m";
string tmp = "";
int diff = 0;
cout << "Schluessel (16 Zeichen):";
if (cin >> tmp) {
if (tmp.length() > 16) {
cerr << RED_start << "\nWerte fuer den Schluessel zu groß. Trenne nach 16 Zeichen ab.\n(" << GREEN_start;
for (int i = 0; i < tmp.length(); i++) {
if (i == 16) {
cerr << RED_start << " | ";
}
cerr << tmp.at(i);
}
cout << ")" << RED_end << endl;
}
if (tmp.length() < 16) {
cerr << RED_start << "\nWert fuer den Schluessel zu klein. Fuelle mit Nullen auf.\n";
diff = 16 - tmp.length();
for (int i = 0; i < diff; i++) {
tmp.push_back('\0');
}
cout << RED_end << endl;
}
for (int i = 0; i < 16; i++) {
key[i] = tmp[i];
}
cout << endl;
}
}
void myECB::enterKlartext() {
string RED_start = "\033[22;31m";
string RED_end = "\033[0m";
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 << RED_start << "\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 << RED_end << 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 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];
}
// Klartext setzen
for (int i = 0; i < 16; i++) {
klartext.push_back(newKlartext[i]);
}
}
void myECB::printSchluessel() {
cout << endl << "Schluessel:\n";
for (int i = 0; i < 4; i++)
cout << hex << "\t0x" << (int) key[0 + i] << "\t0x" << (int) key [4 + i] << "\t0x" << (int) key [8 + i] << "\t0x" << (int) key[12 + i] << endl;
cout << endl;
}
void myECB::printCiphertext() {
cout << endl << "Ciphertext:\n";
for (int i = 0; i < ciphertext.size(); i++) {
cout << std::hex << " 0x" << (int) ciphertext[i];
}
}
void myECB::printKlartext() {
cout << endl << "Klartext:\n";
for (int i = 0; i < klartext.size(); i++) {
cout << std::hex << " 0x" << (int) klartext[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]);
}
}
if (print) {
printSchluessel();
printCiphertext();
printKlartext();
}
}
void myECB::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]);
}
}
if (print) {
printSchluessel();
printKlartext();
printCiphertext();
}
}
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() {
}
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 << RED_end << 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 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];
}
// Klartext setzen
for (int i = 0; i < 16; i++) {
klartext.push_back(newKlartext[i]);
}
}
void myECB::printSchluessel() {
cout << endl << "Schluessel:\n";
for (int i = 0; i < 4; i++)
cout << hex << "\t0x" << (int) key[0 + i] << "\t0x" << (int) key [4 + i] << "\t0x" << (int) key [8 + i] << "\t0x" << (int) key[12 + i] << endl;
cout << endl;
}
void myECB::printCiphertext() {
cout << endl << "Ciphertext:\n";
for (int i = 0; i < ciphertext.size(); i++) {
cout << std::hex << " 0x" << (int) ciphertext[i];
}
}
void myECB::printKlartext() {
cout << endl << "Klartext:\n";
for (int i = 0; i < klartext.size(); i++) {
cout << std::hex << " 0x" << (int) klartext[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]);
}
}
if (print) {
printSchluessel();
printCiphertext();
printKlartext();
}
}
void myECB::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]);
}
}
if (print) {
printSchluessel();
printKlartext();
printCiphertext();
}
}
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() {
}