Vollständige Version anzeigen : [C/C++] AES 256-Bit Ver-Entschlüsselung (DLL)&(NoDLL) [FiNAL]


Golly
08.01.2011, 19:33

Hi,
habe aus langeweile den Advanced Encryption Standard (AES) (;de;wikipedia~org/wiki/Advanced_Encryption_Standard) "from-Scratch" in C geschrieben.
Das ganze ist in einer DLL-Verpackt und über die 5 intuitiven Parameter "AESKey,encryption,OUTPUT,INPUT,sizeof(INPUT)" aufrufbar.

Somit lässt sich auf einfache Weise Sicherheit in Form von Kryptographie in bereits bestehende Projekte integrieren oder hilft weiter den AES-Algorithmus zu verstehen.




[Download (;;;xup~in/dl,55641581/AES-256Bit_CBC;rar/)]



Einbindungsbeispiel (DLL):
//DLL-TESTER AES;dll
#include <windows;h>

typedef void (*pfunc1)(unsigned char*,unsigned char*,int,unsigned char*,int);
pfunc1 AES_dll;

int main()
{
HINSTANCE hLib = LoadLibrary("AES;dll");
if(hLib==NULL)
{
return 1;
}
char dllpath[70];
GetModuleFileName((HMODULE)hLib,(LPTSTR)dllpath,70);
AES_dll = (pfunc1)GetProcAddress((HMODULE)hLib, "AES");
if((AES_dll==NULL))
{
FreeLibrary((HMODULE)hLib);
return 1;
}

unsigned char K[] = {'\x00','\x01','\x02','\x03','\x04','\x05','\x06','\x07','\x08','\x09','\x0 a','\x0b','\x0c','\x0d','\x0e','\x0f','\x10','\x11','\x12','\x13','\x14','\ x15','\x16','\x17','\x18','\x19','\x1a','\x1b','\x1c','\x1d','\x1e','\x1f'} ;
unsigned char input[] = "Ich bin geheim!";
unsigned char temp[sizeof(input)+(16-sizeof(input)%16)];
unsigned char output[sizeof(temp)];

AES_dll(K,1,temp,input,sizeof(input)); //Ver-Schlüsseln
AES_dll(K,0,output,temp,sizeof(temp)); //Ent-Schlüsseln

printf("%s\n",output);

FreeLibrary((HMODULE)hLib);
system("PAUSE");
return 0;
}

Einbindungsbeispiel(NoDLL)[~3x schneller]:


#include <windows;h>
#include "AES;h"

int main()
{
unsigned char K[] = {'\x00','\x01','\x02','\x03','\x04','\x05','\x06','\x07','\x08','\x09','\x0 a','\x0b','\x0c','\x0d','\x0e','\x0f','\x10','\x11','\x12','\x13','\x14','\ x15','\x16','\x17','\x18','\x19','\x1a','\x1b','\x1c','\x1d','\x1e','\x1f'} ;
unsigned char input[] = "Ich bin geheim!";
unsigned char temp[sizeof(input)+(16-sizeof(input)%16)];
unsigned char output[sizeof(temp)];

AES(K,1,temp,input,sizeof(input)); //Ver-Schlüsseln
AES(K,0,output,temp,sizeof(temp)); //Ent-Schlüsseln

printf("%s\n",output);

system("PAUSE");
return 0;
}





Einzige noch vorhandene Negativ-Punkte :
-es wird nur die höchste Schlüssellänge von 256Bit angeboten (128 und 192 können auf Anfrage von mir nachintegriert werden, jedoch nicht umbedingt sinnvoll)

Wenn Interesse am mathematischen Hintergrund bzgl. der MixColumns bzw. der InvMixColumns Operation besteht, kann der Code zur eigentlichen Berrechnung dieser von mir geuppt werden, da zZt. im aktuellen Code aus Performance-Gründen bereits vorgerechnete Tabellen verwendet werden.

Habt erbarmen mit mir, das ist das erste mal, dass ich eine DLL geschrieben habe, das DLL-Gerüst ist aus irgent nem Tut gerippt und evtl teilweise redundant, kein Plan. Evtl. Fehler bitte posten, bin jetzt nicht allzu erfahren in C.


*Bugs:
-(Performance-Verbesserung) Shift_Mix_Add mit SubBytes zusammenfassen

*Bugfixes:
-Padding optimiert
-Padding-Strip gefixt

Hardware Preisvergleich | Amazon Blitzangebote!

Videos zum Thema
Video Loading...
razor90
08.01.2011, 22:43

*ShiftRows lässt sich sicherlich eleganter lösen, aber es funkt :D

Geh mal dem Tipp auf Wikipedia nach und fasse Sub, Shift und Mix mit Hilfe von 4 Arrays zu einer Funktion zusammen ;)
Es sich selbst herzuleiten ist zwar schwer und man sieht am Ende nicht mehr, was der Code eigentlich macht, aber der Geschwindigkeitsgewinn ist groß.
Bin damit auf ~600 mb/s mit einem i5-750 und 128-bit Key gekommen.

mfg,
r90


Golly
08.01.2011, 23:08

Habe es mir jetzt paar mal durchgelesen die Stelle, aber blicke nicht so ganz durch wie man die drei nochmals zusammenfassen könnte.

Also vor allem wie man ShiftRows zu einer Tabelle machen will, da es ja nicht vom Input-Byte ansich sondern den anderen abhängt, da dort ja keine Rechenoperation sondern nur eine "Verschiebung"/"Umverdrahtung" geschieht.

600Mb/s klingen aber schonmal sehr verlockend

Habe meinen Code schon zig Verbesserungen bzgl. Performance nach bestem Wissen und Gewissen unterzogen, wüsste auch nicht was man da noch machen könnte ohne jetzt wo anders was abzukupfern.

Ansonsten habe ich ja bereits vorgerechnete Tabellen, wobei ich sagen muss, dass ich mir selber einen Schulterklopfer geben musste, als ich gesehen habe, dass TrueCrypt die exakt gleichen Tabellen verwendet (jetzt bei MixColumn und InvMixColumn).

//EDIT:

Ich glaub ich weiß jetzt wies gemeint ist.
Statt seperat ShiftRows zu machen, einfach anderen Offset in anderen Operationen verwenden.
Werds nun ausprobieren und nachher Ergebnis posten.


razor90
09.01.2011, 01:00

Habe es mir jetzt paar mal durchgelesen die Stelle, aber blicke nicht so ganz durch wie man die drei nochmals zusammenfassen könnte.

Also vor allem wie man ShiftRows zu einer Tabelle machen will, da es ja nicht vom Input-Byte ansich sondern den anderen abhängt, da dort ja keine Rechenoperation sondern nur eine "Verschiebung"/"Umverdrahtung" geschieht.

600Mb/s klingen aber schonmal sehr verlockend

Habe meinen Code schon zig Verbesserungen bzgl. Performance nach bestem Wissen und Gewissen unterzogen, wüsste auch nicht was man da noch machen könnte ohne jetzt wo anders was abzukupfern.

Ansonsten habe ich ja bereits vorgerechnete Tabellen, wobei ich sagen muss, dass ich mir selber einen Schulterklopfer geben musste, als ich gesehen habe, dass TrueCrypt die exakt gleichen Tabellen verwendet (jetzt bei MixColumn und InvMixColumn).

//EDIT:

Ich glaub ich weiß jetzt wies gemeint ist.
Statt seperat ShiftRows zu machen, einfach anderen Offset in anderen Operationen verwenden.
Werds nun ausprobieren und nachher Ergebnis posten;


Exakt.
Außerdem kann man SubBytes und MixColumns kombinieren und durch 4 Arrays (deren Herleitung absoluter Brainfuck ist) in einem Schritt durchführen. Dazu noch das AddRoundKey reinhauen und man hat aus vier Funktionen eine gemacht ;)

Bei mir siehts so aus:
void SubShiftMixAdd(const uint8 *in, uint8 *out, const uint8 *key)
{
unsigned int* pKey = (unsigned int*)&key[0];
unsigned int* pIn = (unsigned int*)&in[0];
unsigned int* pOut = (unsigned int*)&out[0];

uint32 a1, a2, a3, a4;

uint32 i1 = pIn[0];
uint32 i2 = pIn[1];
uint32 i3 = pIn[2];
uint32 i4 = pIn[3];

a1 = i1 & 0xFF;
a2 = (i2 & 0xFF00) >> 8;
a3 = (i3 & 0xFF0000) >> 16;
a4 = (i4 & 0xFF000000) >> 24;
*pOut++ = (SubMix1[a1] ^ SubMix2[a2] ^ SubMix3[a3] ^ SubMix4[a4]) ^ *pKey++;

a1 = (i2 & 0xFF);
a2 = (i3 & 0xFF00) >> 8;
a3 = (i4 & 0xFF0000) >> 16;
a4 = (i1 & 0xFF000000) >> 24;
*pOut++ = (SubMix1[a1] ^ SubMix2[a2] ^ SubMix3[a3] ^ SubMix4[a4]) ^ *pKey++;

a1 = (i3 & 0xFF);
a2 = (i4 & 0xFF00) >> 8;
a3 = (i1 & 0xFF0000) >> 16;
a4 = (i2 & 0xFF000000) >> 24;
*pOut++ = (SubMix1[a1] ^ SubMix2[a2] ^ SubMix3[a3] ^ SubMix4[a4]) ^ *pKey++;

a1 = (i4 & 0xFF);
a2 = (i1 & 0xFF00) >> 8;
a3 = (i2 & 0xFF0000) >> 16;
a4 = (i3 & 0xFF000000) >> 24;
*pOut++ = (SubMix1[a1] ^ SubMix2[a2] ^ SubMix3[a3] ^ SubMix4[a4]) ^ *pKey++;
}


Nochmal zu der Geschwindigkeit:
Hab's grad nochmal durchgetestet und gemerkt, dass die 600 mb/s nur bei 4 Threads, x64 und übertaktung erreicht werden ^^ Bei einem Thread und normaler Taktung sind es in-place bei x32 110mb/s und bei x64 160mb/s.
x64 ist schneller, weil laut disasm die extra Register genutzt werden.


Golly
09.01.2011, 01:09

Verdammt bin ich gut :P

Deinen Code schaue ich mir erstmal nicht an, mein Kopf tut so schon weh...
Werde wie gesagt, zunächst das mit den verschobenem Offset probieren, dann guck ich mal wie ich den Rest noch zusammenfasse.

Mit 110-160mb/s liegt man ja schon nahe an den Werten von meinem TrueCrypt Benchmark.
Hatte mir den TrueCrypt-Code nicht weiter angeschaut, bis auf wie gesagt die gleichen Tabellen die mir sofort ins Auge gestochen sind.
Da wird aber auch viel mit Assembler gearbeitet.


razor90
09.01.2011, 01:24

Verdammt bin ich gut :P

Deinen Code schaue ich mir erstmal nicht an, mein Kopf tut so schon weh...
Werde wie gesagt, zunächst das mit den verschobenem Offset, dann guck ich mal wie ich den Rest noch zusammen fasse;


Hehe, so ging es mir damals auch und jetzt wieder beim Anblick meines alten Codes^^
Arbeite dich am besten Schritt für Schritt vor, dann kann man es sogar halbwegs verstehen ;)

Hast du deinen Code eigentlich schon mit Test-Vektoren getestet?

Mit 110-160mb/s liegt man ja schon nahe an den Werten von meinem TrueCrypt Benchmark.
Hatte mir den TrueCrypt-Code nicht weiter angeschaut, bis auf wie gesagt die gleichen Tabellen die mir sofort ins Auge gestochen sind.
Da wird aber auch viel mit Assembler gearbeitet;


Jo, ist bei mir auch fast genau so schnell wie der TrueCrypt-Bench. Die letzten paar mb/s bekommt man nur noch mit ASM und evtl. SSE. Aber ob sich der Aufwand als Hobbyist lohnt?
Ich habe z;B. nur die Verschlüsselung implementiert. Für die Entschlüsselung fehlte mir dann die Lust^^


Golly
09.01.2011, 01:26

Was meinst du mit Test-Vektoren ?

Habe da paar Beispiel Inputs/Keys vom Rijndael-Inspektor und vom NIST-Paper, wenn du das meinst.

Sehe ich auch so, man muss nicht übertreiben, zumal ich mit dem Algo von vornherein auch keine großen Dateien ver-/ent-schlüsseln wollte.


razor90
09.01.2011, 01:32

Was meinst du mit Test-Vektoren ?

Habe da paar Beispiel Inputs/Keys vom Rijndael-Inspektor und vom NIST-Paper, wenn du das meinst;


Genau die meine ich :D


Golly
09.01.2011, 01:38

/////////////////////////////// UPDATE //////////////////////////////////////////

-Ver-&Ent-Schlüsselung optimiert (nach Rat von razor90 und nach bestem Wissen und Gewissen - bis auf SubBytes ~;~)
-CBC-Modus eingebaut
-Aus Performance-Gründen (3x schneller) wird der Code in "eigenständige" Header-Datei (ohne Umweg über DLL) ausgelagert und zusätzlich angeboten.

///////////////////////////////////////////////////////////////////////////////////

Das ganze sollte jetzt wie gewünscht laufen, wurde jedoch aus Zeitmangel noch nicht auf Herz und Nieren getestet.


Ähnliche Themen zu [C/C++] AES 256-Bit Ver-Entschlüsselung (DLL)&(NoDLL) [FiNAL]
  • Hilfe bei Hash-Entschlüsselung
    Hey Jungs und Mädels ;) ich bräuchte da mal eure Hilfe, und zwar müsste ich einen Hash, nennen wir es mal ''entschlüsselt'' haben. Habe schon diverse Seiten im Internet durch, die aber nichts gefunden haben. So bin ich auf euch gestoßen. Hoffe ihr könnt mir helfen? Könnt mir gerne auch [...]

  • Entschlüsselung durch BruteForce
    Hey leutz, hab da mal ne Frage. Und zwar wenn ich jetzt ein paar Daten mit irgendeinem Verschlüsselungsstandart verschlüssele (egal ob synchron oder asynchron) und jemand anders versucht auf welche Art auch immer an den schlüssel zu kommen, wie merkt derjenige wann er ihn hat? ich mein versucht [...]

  • [Code] vigenere entschlüsselung
    bräuchte hilfe bei der entschlüsselung von vigenere am vigenere quadrat... wie bekomme ich schlüssel , geheimtext und klartext raus wenn ich jeweils 2 davon gegeben habe ? .. es geht sich jetz hauptsächlich ums ablesen am quadrat.... schnelle hilfe wär nice ;) bw geht klar erledigt// [...]

  • md5 Entschlüsselung
    Guten Abend Leute des guten Geschmacks Ich habe mir mit nem tollen md5 generator online ne md5 version von nem text erstellt: ;;0;xup~in/exec/ximg;php?fid=11790528 (;;;onlinetools24~de/md5-generator;php) Dann wollte ich mit meinen Rainbowtables, die ich mir hier (;;;freerainbowtables~com/inde [...]



raid-rush.ws | Imprint & Contact pr