2012-06-18 3 views
1

Я пишу приложение, используя библиотеку crypto ++. Для тех, кто не знаком с этим, классы шаблонов ECB_Mode наследуют от CipherModeBase. Программа компилируется и запускается, но вывод, который я получаю, неверен. Когда я вызываю метод шифрования из cipher_object, он работает не так, как если бы я напрямую использовал объект ECB_Mode. Я проверил, что переменные экземпляра объекта опций получаются правильно. Я хотел бы создать экземпляры в структуре if_then_else или switch_case, чтобы я мог сохранить код красивым и сухим. Что я делаю не так?создание объекта из шаблона на основе ввода пользователем

Вот что я пытаюсь, но не работает:

CipherModeBase *cipher_object; 
    cipher_object == NULL; 

    if(options->cipher == BS_AES) 
    { 
     ECB_Mode<AES >::Encryption ecbEncryption(options->key, options->keylen); 
     cipher_object = &ecbEncryption; 
    } 
    else if(options->cipher == BS_TWOFISH) 
    { 
     ECB_Mode<Twofish >::Encryption ecbEncryption(options->key, options->keylen); 
     cipher_object = &ecbEncryption;  
    } 
cipher_object->processData(args); 

Вот что делает работу:

ECB_Mode<AES >::Encryption ecbEncryption(options->key, options->keylen); 
ecbEncryption.processData(args); 

PS. Я не знаю, как использовать режим ECB. Я просто не хочу возиться с IV, пока не смогу заставить все работать. Я также относительно неопытен с C++.

ответ

1

здесь:

cipher_object == NULL; 

if(options->cipher == BS_AES) 
{ 
    // v 
    ECB_Mode<AES >::Encryption ecbEncryption(options->key, options->keylen); 
    cipher_object = &ecbEncryption; 
} 

ecbEncryption является локальным для этой сферы. Вы сохраняете адрес локального и используете его после выхода из области видимости. Это неопределенное поведение. Вы должны передать его в куче, используя новое ключевое слово:

if(options->cipher == BS_AES) 
{ 
    cipher_object = new ECB_Mode<AES >::Encryption(options->key, options->keylen); 
} 

Вы должны сделать то же самое для другой, если заявление.

отметить также, что это:

cipher_object == NULL; 

Должен быть изменен следующим образом:

cipher_object = NULL; 

Проблема должна быть решена с помощью приведенного выше кода, хотя.

+0

Спасибо! Это сработало. Хороший улов на операторе сравнения, возможно, его время, чтобы сделать перерыв ... – user1456786

+0

После того, как вы закончите использовать его, вам также нужно будет запомнить «удалить cipher_object». –

2

Ваши объекты ecbEncryption объявлены в стеке в пределах if и else. (Области - это вещи, заключенные в фигурные скобки).

Объект будет уничтожен, когда область действия объявлена ​​в выходы. Таким образом, объект, который вы вызываете processData on, был удален до вызова этого метода. Ясно, что это не сработает.

Один из вариантов - вы можете объявить объекты в куче вместо стека. Таким образом, жизнь может контролироваться так, как вы хотите.

Попробуйте использовать std :: unique_ptr для cipher_object вместо необработанного указателя. Тогда, в случае и еще пункты назначения ему нравится:

cipher_object.reset(new ECB_Mode<AES>::Encryption(options->key, options->keylen)); 

Тогда объект будет оставаться в куче до конца области видимости cipher_object в, и в этот момент unique_ptr удалит его для вас. И область видимости cipher_object будет продолжаться до тех пор, пока вы не назовете какие-либо методы на ней.

Смежные вопросы