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。我知道不要使用欧洲央行模式。在一切正常之前,我只是不想弄乱IV。我对 C++ 也相对缺乏经验。

4

2 回答 2

2

您的 ecbEncryption 对象在 if 和 else 范围内的堆栈上声明。(范围是用大括号括起来的东西)。

当对象声明的范围退出时,对象将被销毁。因此,在您调用该方法之前,您调用 processData 的对象已被删除。显然那是行不通的。

一种选择是您可以在堆而不是堆栈上声明对象。这样,可以控制生命周期以按照您想要的方式工作。

尝试对 cipher_object 使用 std::unique_ptr 而不是原始指针。然后,在 if 和 else 子句中分配给它,如下所示:

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

然后该对象将保留在堆上,直到 cipher_object 范围结束,此时 unique_ptr 将为您删除它。并且,cipher_object 的作用域将持续到您对其调用任何方法之后。

于 2012-06-18T14:55:15.163 回答
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;

不过,问题应该使用上面的代码来解决。

于 2012-06-18T14:50:58.910 回答