我正在使用crypto ++库编写应用程序。对于那些不熟悉它的人,ECB_Mode模板类继承自CipherModeBase。程序编译并运行,但我得到的输出是不正确的。当我从cipher_object调用加密方法时,它的工作方式与我直接使用ECB_Mode对象的方式不同。我已经验证了正确分配了选项对象实例变量。我想在if_then_else结构或switch_case中创建实例,这样我就可以保持代码的良好和DRY。我做错了什么?
以下是我正在尝试但不起作用的内容:
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 ++也缺乏经验。
答案 0 :(得分:2)
您的ecbEncryption对象在if和else作用域内的堆栈上声明。 (范围是用大括号括起来的东西)。
在退出时声明对象的范围将被销毁。因此,在调用该方法之前,您正在调用processData的对象已被删除。显然这是行不通的。
一个选项是您可以在堆上声明对象而不是堆栈。这样,可以控制生命周期以按照您想要的方式工作。
尝试使用std :: unique_ptr作为cipher_object而不是原始指针。然后,在if和else子句中分配给它:
cipher_object.reset( new ECB_Mode<AES>::Encryption(options->key, options->keylen) );
然后,对象将保留在堆上,直到cipher_object的范围结束,此时unique_ptr将为您删除它。并且,cipher_object的范围将持续到您调用任何方法之后。
答案 1 :(得分:1)
下面:
cipher_object == NULL;
if(options->cipher == BS_AES)
{
// v
ECB_Mode<AES >::Encryption ecbEncryption(options->key, options->keylen);
cipher_object = &ecbEncryption;
}
ecbEncryption
是该范围的本地。您正在存储本地的地址,并在超出范围后使用它。这是未定义的行为。您应该使用new关键字在堆上分配它:
if(options->cipher == BS_AES)
{
cipher_object = new ECB_Mode<AES >::Encryption(options->key, options->keylen);
}
你应该对另一个if语句做同样的事。
另请注意:
cipher_object == NULL;
应改为:
cipher_object = NULL;
但问题应该使用上面的代码来解决。