Crypto++ spinnt?
-
Hi @ll.
Hab eine kleine Crypto-Klasse geschrieben und zerbreche mir den Kopf über folgende Probleme:
Im Debug-Modus Funktioniert die Klasse Tadellos.
Aber sobald man Release auswählt geht es richtig los.Der Cypher Output ändert sich von 'xFbDZxhYwDO4ihspX2/pIw==' nach 'Dvp0NXeWw1ccdfPxcMd1dQ=='. (Passwort und PlainText werden nicht geändert!)
Encrypten funktioniert aber decrypten nicht!
Beim decrypten bekomme ich diese Fehlermeldung:
http://img181.imageshack.us/img181/1125/errornk1.jpgHab Crypto++ neu compiled, half nicht.
Ich hoffe das es nur eine Kleinigkeit ist.
Greets StYleZNOTICE: Ich nutze base64.h nur zum Test ... sobald es mit einleuchtet wie man des base64 von Crypto++ nutzt, werde ich es auch tun
main.cpp
#include <windows.h> #include <iostream> #include "crypt.h" #include "stdafx.h" #include "base64.h" using namespace std; int main(int argc, char* argv[]) { crypt c; c.setpw("bla"); cout<<c.encrypt("blubb").c_str()<<endl; cout<<c.decrypt("xFbDZxhYwDO4ihspX2/pIw==").c_str()<<endl; //DEBUG system("PAUSE"); return 0; }
stdafx.h
// stdafx.h : include file for standard system include files, // or project specific include files that are used frequently, but // are changed infrequently // #pragma once #ifndef _WIN32_WINNT // Allow use of features specific to Windows XP or later. #define _WIN32_WINNT 0x0501 // Change this to the appropriate value to target other versions of Windows. #endif // Crypto++ Library #ifdef _DEBUG # pragma comment ( lib, "cryptlibd" ) #else # pragma comment ( lib, "cryptlib" ) #endif #include <iostream> using namespace std; using std::cout; using std::endl; // TODO: reference additional headers your program requires here
crypt.h
#include "stdafx.h" #include "base64.h" //#include "serpent.h" #include "aes.h" #include "modes.h" // xxx_Mode< > #include "filters.h" // StringSource and // StreamTransformation // Cipher Modes // //#define CIPHER_MODE CBC_CTS_Mode #define CIPHER_MODE CBC_Mode //#define CIPHER_MODE CFB_FIPS_Mode //#define CIPHER_MODE CFB_Mode //#define CIPHER_MODE CTR_Mode //#define CIPHER_MODE ECB_Mode //#define CIPHER_MODE OFB_Mode class crypt { private: string password; string CipherText; string PlainText; string RecoveredText; byte key[ CryptoPP::/*Serpent*/AES::MAX_KEYLENGTH ]; byte iv[ CryptoPP::/*Serpent*/AES::BLOCKSIZE ]; public: crypt(); ~crypt(); string encrypt(string pt); string decrypt(string ct); void setpw(string pw); };
crypt.cpp
#include "crypt.h" crypt::crypt() { ::memset( key, 0x10, CryptoPP::/*Serpent*/AES::MAX_KEYLENGTH ); ::memset( iv, 0x01, CryptoPP::/*Serpent*/AES::BLOCKSIZE ); } crypt::~crypt() { } string crypt::encrypt(string pt) { PlainText = CipherText = RecoveredText = ""; PlainText = pt; CryptoPP::CIPHER_MODE< CryptoPP::/*Serpent*/AES >::Encryption Encryptor( ( byte*)password.c_str(), sizeof(key), iv ); CryptoPP::StringSource( PlainText, true, new CryptoPP::StreamTransformationFilter( Encryptor, new CryptoPP::StringSink( CipherText ) ) ); return Base64::encode(CipherText); } string crypt::decrypt(string ct) { PlainText = CipherText = RecoveredText = ""; CipherText = Base64::decode(ct); CryptoPP::CIPHER_MODE< CryptoPP::/*Serpent*/AES >::Decryption Decryptor( ( byte*)password.c_str(), sizeof(key), iv ); CryptoPP::StringSource( CipherText, true, new CryptoPP::StreamTransformationFilter( Decryptor, new CryptoPP::StringSink( RecoveredText ) ) ); return RecoveredText; } void crypt::setpw(string pw) { password = pw; }
-
Du Held
//... string crypt::encrypt(string pt) { PlainText = CipherText = RecoveredText = ""; PlainText = pt; // >>>>>>>>>>> // CryptoPP::CIPHER_MODE< CryptoPP::/*Serpent*/AES >::Encryption // Encryptor( ( byte*)password.c_str(), sizeof(key), iv ); init_key(); CryptoPP::CIPHER_MODE< CryptoPP::/*Serpent*/AES >::Encryption Encryptor( key, sizeof(key), iv ); // <<<<<<<<<<< CryptoPP::StringSource( PlainText, true, new CryptoPP::StreamTransformationFilter( Encryptor, new CryptoPP::StringSink( CipherText ) ) ); return Base64::encode(CipherText); } private: void init_key() { // wir basteln uns einen key aus dem passwort memset(key, 0, sizeof(key)); if (!password.empty()) { size_t const len = (std::max)(sizeof(key), password.size()); for (size_t i = 0; i < len; i++) key[i % sizeof(key)] ^= password[i % password.size()]; } } //...
Analog dazu beim dekodieren.
Wenn du "sizeof(key)" übergibst, dann liest der auch "sizeof(key)" bytes. In deinem Fall dann ab "password.c_str()". Und das is einfach falsch, wenn der String da drin nicht lang genug ist. Tjo.
p.S.: warums beim Debug geht? Na, weil der Compiler beim Debug vermutlich mehr Platz zwischen Heap-Allokationen lässt, so dass Bytes, die die Crypto++ "hinter" dem Passwort liest, einen immer gleichen Wert haben (nämlich den "no-mans-land-fill" - 0xFD oder sowas). Im Release is das nicht so, und daher funktionierts dann nimmer.