Получение случайного вывода из Crypto++

Не могу понять, почему я получаю, казалось бы, случайный вывод из декодера Crypto++ RC2. Вход всегда один и тот же, но выход всегда разный.

const char * cipher     ("o4hk9p+a3+XlPg3qzrsq5PGhhYsn+7oP9R4j9Yh7hp08iMnNwZQnAUrZj6DWr37A4T+lEBDMo8wFlxliuZvrZ9tOXeaTR8/lUO6fXm6NQpa5P5aQmQLAsmu+eI4gaREvZWdS0LmFxn8+zkbgN/zN23x/sYqIzcHU");
int          keylen     (64);

unsigned char keyText[] = { 0x1a, 0x1d, 0xc9, 0x1c, 0x90, 0x73, 0x25, 0xc6, 0x92, 0x71, 0xdd, 0xf0, 0xc9, 0x44, 0xbc, 0x72, 0x00 };
std::string key((char*)keyText);

std::string data;
CryptoPP::RC2Decryption rc2(reinterpret_cast<const byte *>(key.c_str()), keylen);
CryptoPP::ECB_Mode_ExternalCipher::Decryption rc2Ecb(rc2);
CryptoPP::StringSource
    ( cipher
    , true
    , new CryptoPP::Base64Decoder
        ( new CryptoPP::StreamTransformationFilter
            ( rc2Ecb
            , new CryptoPP::StringSink(data)
            , CryptoPP::BlockPaddingSchemeDef::NO_PADDING
            )
        )
    );

std::cout << data << '\n';

person Don Reba    schedule 16.09.2010    source источник
comment
Пожалуйста, приведите полный пример: нет ничего явно неправильного в том, что вы нам показываете, поэтому я думаю, что проблема заключается в том, что вы нам не показываете (т. е. где находятся ключ, кейлен и шифр). родом из?)   -  person Rasmus Faber    schedule 16.09.2010
comment
Это просто константы, определенные выше, и они правильно расшифровываются в Java с помощью RC2/ECB/NOPADDING.   -  person Don Reba    schedule 16.09.2010
comment
А, я вижу, ты сам догадался. Как вы видите, константа может быть важна: не было очевидно, была ли keylen длина key или (как это было в случае) эффективная длина ключа.   -  person Rasmus Faber    schedule 16.09.2010


Ответы (2)


Параметры конструктора RC2::Decryption: (указатель на ключевые байты, длина ключевых байтов). Вы даете ему указатель на 16 байтов, но используете длину 64 байта. Crypto++ считывает неинициализированную память при чтении ключа, поэтому вы получаете случайные результаты.

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

CryptoPP::RC2Decryption rc2(keyText, 16, keylen);

Обратите внимание, что вы не должны не использовать std::string для хранения ключа. Ключ может содержать 0x00 байт, и std::string не предназначен для их хранения.

person Rasmus Faber    schedule 16.09.2010
comment
Ты неправ. std::string предназначен для хранения любого элемента типа char, включая '\0'. См. Бьярн Страуструп Язык программирования C++, 4-е изд., стр. 1041 (стр. 583 в 3-м изд.). - person user515430; 11.03.2014

RC2Decryption должен был быть определен как:

CryptoPP::RC2Decryption rc2(reinterpret_cast<const byte *>(key.c_str()), key.size(), keylen);
person Don Reba    schedule 16.09.2010