使用 Boost::asio::async_send_to 发送加密数据时出错
Error while sending encrypted data with 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;
}
更新:接收函数代码:
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
函数中解密。
没有加密一切都很好。发送的字节数总是正确的,在接收方也是如此。 de "CD"- 块的长度是相当随机的。我已经检查过加密,解密后的数据与原始明文相同。
有人知道这种行为从何而来吗?
这里的关键是错误数据在加密数据数组中的第一个空值 (0x00) 之后开始。下面一行:
strcpy(newSendBuffer, encSendBuffer.c_str());
...看起来它只是将数据复制到该空字节到 newSendBuffer 中。 send 函数发送缓冲区内容就好了;缓冲区只是没有您期望的数据。您需要以不同的方式加载 newSendBuffer,而不是使用可以处理空字节的 strcpy()。尝试 std::memcpy()。
谢谢 Joachim Pileborg 和 Jack O'Reilly!你说的没错。
我更改了我的代码 strcpy(newSendBuffer, encSendBuffer.c_str());
到
for (int i = 0; i < encSendBuffer.length(); i++)
{
newSendBuffer[i] = encSendBuffer.at(i);
}
在发送方和接收方。它实际上解决了问题。这是非常幼稚的代码,但它做了它应该做的事情。
std::memcpy()
好像优雅多了我试试看
我正在开发实时通信应用程序的加密版本。我遇到的问题是,发送到接收方的加密数据包有问题。错误日志中的一个示例:(十六进制编码数据,原始数据是纯字节码)。
已发送: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;
}
更新:接收函数代码:
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
函数中解密。
没有加密一切都很好。发送的字节数总是正确的,在接收方也是如此。 de "CD"- 块的长度是相当随机的。我已经检查过加密,解密后的数据与原始明文相同。
有人知道这种行为从何而来吗?
这里的关键是错误数据在加密数据数组中的第一个空值 (0x00) 之后开始。下面一行:
strcpy(newSendBuffer, encSendBuffer.c_str());
...看起来它只是将数据复制到该空字节到 newSendBuffer 中。 send 函数发送缓冲区内容就好了;缓冲区只是没有您期望的数据。您需要以不同的方式加载 newSendBuffer,而不是使用可以处理空字节的 strcpy()。尝试 std::memcpy()。
谢谢 Joachim Pileborg 和 Jack O'Reilly!你说的没错。
我更改了我的代码 strcpy(newSendBuffer, encSendBuffer.c_str());
到
for (int i = 0; i < encSendBuffer.length(); i++)
{
newSendBuffer[i] = encSendBuffer.at(i);
}
在发送方和接收方。它实际上解决了问题。这是非常幼稚的代码,但它做了它应该做的事情。
std::memcpy()
好像优雅多了我试试看