AES: Test und Meinung



  • Naja, was bei deinem Code rauskommt ist eher Zufall als Verschlüsselung.
    Du solltest dich mal mit Pointern und Zeichenkettenrepräsentation in C/C++ beschäftigen, das gelernte dann wieder verdrängen und std::string nehmen 😉 Kurz gesagt: in einen char passt nur ein einzelnes Zeichen.

    Ein Beispiel:

    #include <iostream>
    
    #include "aes.h"
    
    int main( )
    {
    	std::string input;
    	std::string password;
    
        // Eine Zeile nach 'input' lesen:
    
    	std::cout << "Bitte geben Sie den zu verschluesselnden Text ein:\n";
    	std::getline( std::cin, input );
    
        // Ein Wort als Key nach 'password' lesen:
    
    	std::cout << "Bitte geben Sie ein Passwort ein: ";
    	std::cin >> password;
    
        // Eine 'aes'-Instanz:
    
    	aes AES;
    
        // Den Text zur Kontrolle einmal als Text, einmal als Hex-Werte ausgeben:
    
    	std::cout << "\n\nUnverschluesselter Text:\t\"" << input << "\"\n";
    	std::cout << "Unverschluesselte Daten:\t";
    
    	for( std::string::iterator i = input.begin( ); i != input.end( ); ++i ) {
    
    		std::cout << "0x";
    		std::cout.width( 2 );
    		std::cout.fill( '0' );
    		std::cout << std::hex << static_cast< int >( *i ) << " ";
    	}
    
        // Ein char-Array zum rumspielen mit AES daraus backen:
    
    	size_t length = input.length( );
    
    	char *data = new char[ length ];
    	std::copy( input.begin( ), input.end( ), data );
    
    	std::cout << "\n\nVerschluesselung...\n\n"; // <- nomen est omen
    
    	size_t blocks = AES.encrypt( &data, length, const_cast< char* >( password.c_str( ) ) );
    
        // Verschluesselte Daten ausgeben (nur Hex, als Zeichenkette bringt's ned wirklich was...)
    
    	std::cout << "Verschluesselte Daten:\t\t";
    
    	for( size_t i = 0; i < ( blocks * 16 ); ++i ) { // wir haben 'blocks' blöcke à 16 Bytes bekommen
    
    		std::cout << "0x";
    		std::cout.width( 2 );
    		std::cout.fill( '0' );
    		std::cout << std::hex << ( static_cast< int >( data[ i ] ) & 0x0ff ) << " ";
    	}
    
    	std::cout << "\n\nEntschluesselung...\n\n"; // <- ... one way, or another, i'm gonna ... decrypt u! resistance is futile!!!111elf *sing*
    
    	AES.decrypt( &data, blocks * 16, const_cast< char* >( password.c_str( ) ) ); // vorsicht: mehr Daten!
    	length = strlen( data );
    
        // Entschluesselte Daten als Hex-Werte und Text anzeigen.
    
        std::cout << "Entschluesselte Daten:\t\t";
    
    	for( size_t i = 0; i < length; ++i ) {
    
    		std::cout << "0x";
    		std::cout.width( 2 );
    		std::cout.fill( '0' );
    		std::cout << std::hex << ( static_cast< int >( data[ i ] ) & 0x0ff ) << " ";
    	}
    
    	std::cout << "\nEntschluesselter Text:\t\t" << data << std::endl;
    }
    

    cheers, Swordfish



  • Wenn du nach 2 Jahren immer noch Kommentare zum Code willst: das Ganze in 'ne Klasse zu packen find ich haesslich 😉



  • Mich wundert dass noch niemand was über die IMO grauenhafte Idee gesagt hat Speicher in der encrypt/decrypt Funktion zu reallokieren.



  • @Blue-Tiger: Ich nach zwei jahren auch 😉
    @hustbaer: Sorry, *kleinlaut* ich sag's ja: Den Speicher in encrypt/decrypt zu realloziieren ist GRAUENHAFT!

    Mal sehen, wahrscheinlich werd ichs refaktorieren und noch Blowfish dazustricken.

    cheers, Swordfish



  • Hi @ll
    beim compilieren kommt es leider zu Fehlern:

    Erzeugen
      [Linker Fehler] Unresolved external 'aes::~aes()' referenced from C:\DOKUMENTE UND EINSTELLUNGEN\ADMINISTRATOR\DESKTOP\AESTETE\UNIT1.OBJ
      [Linker Fehler] Unresolved external 'aes::aes()' referenced from C:\DOKUMENTE UND EINSTELLUNGEN\ADMINISTRATOR\DESKTOP\AESTETE\UNIT1.OBJ
      [Linker Fehler] Unresolved external 'aes::encrypt(char * *, unsigned int, char *)' referenced from C:\DOKUMENTE UND EINSTELLUNGEN\ADMINISTRATOR\DESKTOP\AESTETE\UNIT1.OBJ
      [Linker Fehler] Unresolved external 'aes::decrypt(char * *, unsigned int, char *)' referenced from C:\DOKUMENTE UND EINSTELLUNGEN\ADMINISTRATOR\DESKTOP\AESTETE\UNIT1.OBJ
    

    Könnt ihr mir weiter helfen? 🙄



  • Du musst die .cpp-Datei mitkompilieren.



  • Vielen Dank!
    Jetzt klappt es endlich!

    Edit:
    Könnte jemand, oder der Autor selbst, die Klasse/das Programm so umschreiben, dass man mit AnsiString arbeiten kann. Bin leider ein Anfänger 😢

    Währe sehr nett!
    MFG StYleZ



  • @StYleZ: verwende doch einfach eine Fertige Library wie die crypto++.
    Und was bitte meinst du mit "AnsiString"? Blubb?



  • AnsiString ist ein Datentyp und wird in Borland C++ Builder (VCL) verwendet.

    Zu Crypto++:
    Bisher hab ich nur Tutorials für die Implementierung von Crypto++ in VC++ gefunden.
    Da ich mehr oder weniger Anfänger bin, habe ich keinen schimmer, wie ich Crypto++ im C++ Builder implementieren soll und geschweige den benutzen.

    Deswegen habe ich um ein Beispiel gebeten.



  • StyleZ schrieb:

    Könnte jemand, oder der Autor selbst, die Klasse/das Programm so umschreiben, dass man mit AnsiString arbeiten kann.

    Ne, werd' ich nicht. Wird sonst wahrscheinlich auch keiner. 😃
    Du wirst dich daran gewöhnen müssen, dass Du dich den Bibliotheken anpasst, die du verwendest. (Außer es ist, wie diese AES-Klasse Open Source - aber dann ist es Deine Arbeit, sie anzupassen.)

    AnsiString hat doch IMHO wie std::string eine c_str( ) methode, oder?

    cheers, Swordfish



  • Ja, AnsiString hat diese Methode.



  • Na dann?

    cheers, Swordfish



  • Versuchen werd ich's definitiv.
    Nur ob ich es schaffe. 😉



  • Hi 😃
    Auch wenn das Thema seeehr alt ist, habe ich einige Fragen bzw. Anmerkungen:

    1.) Ab einer bestimmten Schlüssellänge crasht die Klasse bei mir (habe es mit 60 Zeichen und 10 Zeichen getestet, bei 60 crasht es).
    2.) Woher weiß ich, wie groß der Buffer sein muss? Wenn ich das recht sehe, brauche ich z.B. für einen 18-stellen Langen String zum verschlüsseln 2 Blocks (also 32 Byte, richtig?). Muss der Buffer jetzt 32 Bytes groß sein, oder reichen 18?!

    Gruß



  • So sieht jedenfalls keine effiziente AES-Implementierung aus. Ich finde aber leider auch nicht mehr die Veröffentlichung, in der schön erklärt wurde, wie man Ver- und Entschlüsselung schnell mit jeweils vier 32-bittigen Lookuptabellen der Größe 256 erschlagen kann (Te0,Te1,Te2,Te3 und Td0,Td1,Td2,Td3). Die Referenz-Implementierung von 2000 verwendete auch schon diesen Trick.

    Ja, es ist lustig, das mal alles selbst zu implementieren. Habe ich auch schon gemacht, damals in Java. Es dann aber für sicherheitskritische Anwendungen nutzen, ist eine ziemlich blöde Idee. Da verwendet man besser die gut getesteten, open source Bibliotheken.



  • @krümelkacker
    Der Code ist von 2006, wahrscheinlich findet auch Swordfish ihn mittlerweile schrecklich. 😉

    krümelkacker schrieb:

    Es dann aber für sicherheitskritische Anwendungen nutzen, ist eine ziemlich blöde Idee. Da verwendet man besser die gut getesteten, open source Bibliotheken.

    Mal aus Interesse. Angenommen man implementiert das selbst, verschlüsselt dann etwas und "große" Programme können das dann wieder entschlüsseln. (Test natürlich auch umgekehrt machen.)
    Bedeutet das dann nicht, dass der Algorithmus richtig angewendet wird und man eigentlich keine Sicherheitslücken haben sollte? (Im Sinne der Verschlüsselung, Schlüssel im Speicher oder so sind ja noch mal ein anderes Thema.)



  • cooky451 schrieb:

    @krümelkacker
    Der Code ist von 2006, wahrscheinlich findet auch Swordfish ihn mittlerweile schrecklich. 😉

    Daß ich damit nix 'reiß' hab ich damals schon gewusst 😉



  • Algorithmus richtig angewendet != keine Sicherheitslücken



  • Swordfish schrieb:

    Daß ich damit nix 'reiß' hab ich damals schon gewusst 😉

    Aber wie bist du auf die Idee mit dem buf** gekommen, auf den du dann auch noch delete[] aufrufst? 😃

    knivil schrieb:

    Algorithmus richtig angewendet != keine Sicherheitslücken

    Sehr informativ..



  • cooky451 schrieb:

    knivil schrieb:

    Algorithmus richtig angewendet != keine Sicherheitslücken

    Sehr informativ..

    Du setzt zwei Groessen in Relation, die nichts miteinander zu tun haben. Wenn das Programm beispielsweise den Schluessel bei Twitter postet, dann ist es potentiell unsicher. Das hat nichts mit der Funktionsweise des Algorithmus zu tun.


Anmelden zum Antworten