AES: Test und Meinung



  • ich hab den code ma in meinen compiler eingefügt aber der sagt:

    "data.cpp": E2268 Aufruf der undefinierten Funktion '_stricmp' in Funktion main(int,char * *) in Zeile 30
    


  • Dann ist dein Compiler (welcher?) nicht Standardkonform.

    cheers, Swordfish

    PS: Du könntest es mit der POSIX-Funktion stricmp( ) (ohne Unterstrich) versuchen.



  • Dann ist dein Compiler (welcher?) nicht Standardkonform.

    Willst du damit sagen das _stricmp zum C++ Standart gehört? 😮 😮



  • Sorry, hab' mich verlaufen. _stricmp( ) und stricmp( ) sind beide nicht Standard. Die Meisten C/C++ Bibliotheken (glibc, Dinkumware auf jeden Fall) implementieren sie jedoch.

    Da _stricmp( ) nur zur Argumentprüfung verwendet wird, kann man es getrost durch std::strcmp( ) austauschen und beide Strings vor der Prüfung auf Lower-/Uppercase bringen.

    cheers, Swordfish



  • ich hab ma versucht das auf text anzuwenden, den der benutzer selbst eingibt, aber es klappt net:

    #include "aes.h"
    #include <iostream>
    
    using namespace std;
    
    int main()
    {
      aes AES;
    
      char t;
      char p;
    
      char *text = &t;
      char *pwd = &p;
    
      cin >> t;
      cout << "\n";
    
      cin >> p;
    
      AES.encrypt(&text,
      strlen(&t),
      pwd);
    
      cout << "\n";
      cout << "\n";
    
      cout << "Verschlüsselt:\n";
    
      cout << text << endl;
    
      AES.decrypt(&text,
      strlen(&t),
      pwd);
    
      cout << "Entschlüsselt:\n";
    
      cout << text;
    
      return 0;
    }
    

    das is mitlerweile mein 3. versuch aber es will einfach net klappen, abgesehen davon, dass man nur ein zeichen eingeben kann.

    wenn ich

    a
    b
    

    eingebe kommt heraus:

    Verschlüsselt:
    
    V/çàðEŒ/³A;X:
    
    Entschlüsselt:
    
    $I¡QŒ-'ͳôçâ'ÙÄ
    


  • 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.


Anmelden zum Antworten