Ошибка при отправке зашифрованных данных с помощью 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()
кажется, намного элегантнее, и я попробую.