2015-01-29 6 views
3

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

отправлено: 262C1688215232656B5235B691826A21C51D37A99413050BAEADB81D8892493FC0DB519250199F5BE73E18F2703946593C4F6CEA396A168B3313FA689DE84F380606ED3C322F2ADFC561B9F1571E29DF5870B59D2FCF497E01D9CD5DFCED743559C3EE5B00678966C8D73EA3A5CD810BB848309CDF0F955F949FDBA618C401DA70A10C36063261C5DBAB0FC0F1

получил: 262C1688215232656B5235B691826A21C51D37A99413050BAEADB81D8892493FC0DB519250199F5BE73E18F2703946593C4F6CEA396A168B3313FA689DE84F380606ED3C322F2ADFC561B9F1571E29DF5870B59D2FCF497E01D9CD5DFCED743559C3EE5B00CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD

Это вызов посыла-метода:

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; 
} 

UPDATE: код функции приема:

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» довольно случайна. Я уже проверил шифрование, а дешифрованные данные совпадают с исходным текстом.

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

+0

Значение '0xcd' используется отладчиком Visual Studio для неинициализированной памяти. Кажется, что нет ничего неправильного в отправляющем коде (если 'encSendBuffer' является не двоичной строкой (т. Е. Содержит только фактические печатные символы)), поэтому ошибка может быть в коде, принимающем данные. Не могли бы вы показать это тоже? –

+0

Вы также можете использовать сетевой сниффер, например [Wireshark] (https://www.wireshark.org/), чтобы увидеть, что данные, отправленные/полученные, являются правильными данными. –

+0

На самом деле я не могу гарантировать, что содержимое 'encSendBuffer' будет читаемым. Входными данными шифрования является чистый байт-код звуковой карты. Но он всегда выглядит хорошо, прежде чем он будет изменен. Я обновил свой вопрос для получения кода. – DrakeBlack

ответ

4

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

strcpy(newSendBuffer, encSendBuffer.c_str()); 

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

+0

Хороший улов. Я просмотрел его код для чего-то подобного, но не видел его. – jww

0

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

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

в

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

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

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

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