Morbiddeath Ответов: 1

Crypto++, ошибка _BLOCK_TYPE_IS_VALID


Привет, я скопировал этот фрагмент кода с другого сайта и у меня возникли проблемы с его компиляцией; я новичок в криптографии, и хотя я изо всех сил старался заставить это работать, я все время получаю "выражение: _BLOCK_TYPE_IS_VALID(pHead->nBlockUse)" я знаю, что эта ошибка связана с кучей, но я не выполнял никакого удаления в этих нескольких строках кода.

#include "dll.h" 
#include "modes.h"
#include "aes.h"
#include "filters.h"
#include "iostream"
#include "cryptlib.h"


int main(int argc, char* argv[]) {


    //
    // Key and IV setup
    //
	
    byte key[ CryptoPP::AES::DEFAULT_KEYLENGTH ], iv[ CryptoPP::AES::BLOCKSIZE ];
    memset( key, 0x00, CryptoPP::AES::DEFAULT_KEYLENGTH );
    memset( iv, 0x00, CryptoPP::AES::BLOCKSIZE );


    //
    // String and Sink setup
    //
    std::string plaintext = "Now is the time for all good men to come to the aide...";
    string ciphertext;
    std::string decryptedtext;

    //
    // Dump Plain Text
    //
    std::cout << "Plain Text (" << plaintext.size() << " bytes)" <<    std::endl;
    std::cout << plaintext;
    std::cout << std::endl << std::endl;

    //
    // Create Cipher Text
    //
	
	CryptoPP::AES::Encryption aesEncryption(key, CryptoPP::AES::DEFAULT_KEYLENGTH);
    CryptoPP::CBC_Mode_ExternalCipher::Encryption cbcEncryption( aesEncryption, iv );

    CryptoPP::StreamTransformationFilter stfEncryptor(cbcEncryption, new CryptoPP::StringSink(     ciphertext ) ); 
    stfEncryptor.Put( reinterpret_cast<const unsigned char*>( plaintext.c_str() ), plaintext.length() + 1   );
    stfEncryptor.MessageEnd();


	

	
    //
    // Dump Cipher Text
    //
    std::cout << "Cipher Text (" << ciphertext.size() << " bytes)" << std::endl;

    for( unsigned int i = 0; i < ciphertext.size(); i++ ) {

        std::cout << "0x" << std::hex << (0xFF & static_cast<byte>(ciphertext[i])) << " ";
    }

    std::cout << std::endl << std::endl;

    //
    // Decrypt
    //
    
	CryptoPP::AES::Decryption aesDecryption(key, CryptoPP::AES::DEFAULT_KEYLENGTH);
    CryptoPP::CBC_Mode_ExternalCipher::Decryption cbcDecryption( aesDecryption, iv );

    CryptoPP::StreamTransformationFilter * stfDecryptor=new  CryptoPP::StreamTransformationFilter(cbcDecryption, new CryptoPP::StringSink( decryptedtext  ) );
    stfDecryptor->Put( reinterpret_cast<const unsigned char*>( ciphertext.c_str() ), ciphertext.size() );
    stfDecryptor->MessageEnd();

    //
    // Dump Decrypted Text
    //
	
    std::cout << "Decrypted Text: " << std::endl;
    std::cout << decryptedtext;
    std::cout << std::endl << std::endl;

	

    return 0;
}



Хотя стоит отметить, что если я прокомментирую эти две строки, то больше не получу ошибку кучи
stfEncryptor.Put( reinterpret_cast<const unsigned char*>( plaintext.c_str() ), plaintext.length() + 1   );
    stfEncryptor.MessageEnd();


Я действительно пытался отладить его, и ошибка появляется прямо перед последним возвращением 0, я думаю, что в то время как деструктор класса вызывается, де-распределение вызывает эту проблему?


Любая помощь будет очень признательна.

nv3

Я предполагаю, что у вас нет проблем с его компиляцией, потому что упомянутая вами ошибка является ошибкой времени выполнения, которая предполагает, что куча повреждена. Так что у тебя, похоже, проблемы с управлением.

Является ли код, который вы показываете, всем кодом или только той его частью, которая, как вы полагаете, имеет отношение к делу? На первый взгляд все выглядит хорошо.

Morbiddeath

Это весь код, извините, я не знаю, почему я использовал термин компиляция, но он прекрасно компилируется, ошибка выскакивает во время выполнения.

André Kraak

Почему вы используете "plaintext.length() + 1", чтобы указать длину зашифрованного сообщения?
Попробуйте вместо этого " plaintext.length()" и посмотрите, что произойдет.

Morbiddeath

Я предполагаю, что +1 - это нулевой символ, но мне не повезло после удаления +1. Все та же ошибка кучи.

Richard MacCutchan

Почему бы не спросить в том месте, откуда вы скопировали код?

Morbiddeath

Код взят с основного сайта CryptoPP; нет никакого форума, чтобы опубликовать эту ошибку, все, что у меня осталось, - это сайты кодирования.

Morbiddeath

Спасибо, Ричард, очень благодарен; я постараюсь найти там ответ.

mahesh4comp

Привет, я тоже сталкиваюсь с той же проблемой. У меня есть одинаковые настройки в проектах vc как для моего приложения, так и для проекта cryptoapp dll, и я использую VS 2010 (VC 9.0)
Это дает мне такую же проблему с кучей curruption.
Когда объект ciphertext (std:string) выходит за пределы области видимости, он пытается удалить память, которая принадлежит cryptoapp.dll.

Morbiddeath

Эй, а ты пробовал то решение, которое я тебе предложил? В опции генерации кода в VS вы можете попробовать изменить библиотеку времени выполнения на многопоточную отладку или просто многопоточную, это может решить вашу проблему.

Если все остальное не удается, попробуйте использовать Visual Studio 2012 для компиляции библиотеки. Это тоже сработало для меня.

1 Ответов

Рейтинг:
12

Morbiddeath

Я сам нашел решение; при компиляции исходного кода CryptoPP, в свойства раствора(cryptdll), под C/C++ меню есть подменю под названием генерация кода, поле библиотека времени выполнения должно быть Многопоточная отладочная библиотека DLL (/MDd)- Спасибо, что уделили мне время, ребята. Прощание.