Ошибка при отправке зашифрованных данных с помощью Boost::asio::async_send_to

Я разрабатываю зашифрованную версию приложения связи в реальном времени. У меня проблема в том, что зашифрованные пакеты данных, отправленные получателю, являются неисправными. Пример из журнала ошибок: (шестнадцатеричные данные, исходные данные - чистый байтовый код).

послал: 262C1688215232656B5235B691826A21C51D37A99413050BAEADB81D8892493FC0DB519250199F5BE73E18F2703946593C4F6CEA396A168B3313FA689DE84F380606ED3C322F2ADFC561B9F1571E29DF5870B59D2FCF497E01D9CD5DFCED743559C3EE5B00678966C8D73EA3A5CD810BB848309CDF0F955F949FDBA618C401DA70A10C36063261C5DBAB0FC0F1

получено: 262C1688215232656B5235B691826A21C51D37A99413050BAEADB81D8892493FC0DB519250199F5BE73E18F2703946593C4F6CEA396A168B3313FA689DE84F380606ED3C322F2ADFC561B9F1571E29DF5870B59D2FCF497E01D9CD5DFCED743559C3EE5B00CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD

Это вызов метода send:

string encSendBuffer = sj->cipherAgent->encrypt(sj->dFC->sendBuffer, sj->dFC->sendBytes);    

char* newSendBuffer = new char[encSendBuffer.length() + 1];
strcpy(newSendBuffer, encSendBuffer.c_str());

sj->dFC->s->async_send_to(boost::asio::buffer(newSendBuffer, encSendBuffer.length()),
    *sj->dFC->f,
    boost::bind(&sender::sendHandler, this,
    boost::asio::placeholders::error,
    boost::asio::placeholders::bytes_transferred)
)

sj->dFC->s такое UDP-сокет и sj->dFC->f является конечной точкой UDP Код ошибки sendHandler всегда system: 0

Вот как я делаю шифрование с использованием библиотеки Crypto++: (извлечь)

string cipherEngine::encrypt(char* input, int length)
{
    string cipher = "";

    CTR_Mode<AES>::Encryption e;
    e.SetKeyWithIV(key, keyLength, iv);

    ArraySource as((byte*)input, length, true,
        new StreamTransformationFilter(e,
            new StringSink(cipher)
        )
    );

    return cipher;
}

ОБНОВЛЕНИЕ: Код функции приема:

void receiver::receive(){
    int maxLength = 4096;

    sj->dFC->s->async_receive_from(boost::asio::buffer(input,maxLength),
                                   senderEndpoint, 
                                   boost::bind(&receiver::handleReceiveFrom, this, boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred));
}

После получения данных они сохраняются в буфере символов input и расшифровывается в handleReceiveFrom функция.

Без шифрования все нормально. Количество отправляемых байтов всегда корректно, в том числе и на стороне получателя. Длина де "CD"- блоков довольно случайна. Я уже проверил шифрование и расшифрованные данные такие же, как и в оригинальном текстовом формате.

Кто-нибудь знает, откуда такое поведение?

2 ответа

Решение

Ключевым моментом здесь является то, что ошибочные данные начинаются после первого нулевого значения (0x00) в вашем зашифрованном массиве данных. Следующая строка:

strcpy(newSendBuffer, encSendBuffer.c_str());

... похоже, что это только копирование данных до тех пор, пока этот нулевой байт в newSendBuffer. Функция send просто отправляет содержимое буфера; в буфере просто нет ожидаемых данных. Вам нужно будет загрузить newSendBuffer другим способом, не используя strcpy(), который может обрабатывать нулевые байты. Попробуйте std::memcpy().

Спасибо Иоахим Пилеборг и Джек О'Рейли! Вы действительно правы.

Я изменил свой код с strcpy(newSendBuffer, encSendBuffer.c_str());

в

for (int i = 0; i < encSendBuffer.length(); i++)
{
    newSendBuffer[i] = encSendBuffer.at(i);
}

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

std::memcpy() кажется, намного элегантнее, и я попробую.

Другие вопросы по тегам