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

    Hab Crypto++ neu compiled, half nicht.

    Ich hoffe das es nur eine Kleinigkeit ist.
    Greets StYleZ

    NOTICE: 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.


Anmelden zum Antworten