MFC搭建C/S架构时RSA公钥发送异常及优化方案咨询
问题分析与解决方案
当前实现的问题
- 使用
sprintf转换int到字符串存在缓冲区溢出风险,未处理边界情况。 - 发送时直接使用
sizeof(encPubKey_First),会将数组中未使用的垃圾数据一并发送,这是客户端收到异常值的核心原因之一。 - 字符串传输相比二进制传输效率更低,额外增加了编解码的复杂度。
更优实现方式
方式一:直接发送二进制公钥(推荐)
公钥是int类型,直接按二进制字节发送,无需字符串转换,效率更高且避免编码错误。注意统一使用网络字节序(大端序):
服务器发送代码修改:
// 将主机字节序的int转换为网络字节序(大端) uint32_t n_network = htonl(enc.pub_Key_First); uint32_t e_network = htonl(enc.pub_Key_Second); // 依次发送公钥的两个参数 send(socket, &n_network, sizeof(n_network), 0); send(socket, &e_network, sizeof(e_network), 0);
客户端接收代码示例:
uint32_t n_network, e_network; // 接收公钥参数n recv(clnt_socket, &n_network, sizeof(n_network), 0); // 接收公钥参数e recv(clnt_socket, &e_network, sizeof(e_network), 0); // 将网络字节序转换回主机字节序 int pub_Key_First = ntohl(n_network); int pub_Key_Second = ntohl(e_network);
方式二:安全字符串传输(若需字符串格式)
使用安全的字符串格式化函数替代sprintf,并仅发送实际有效字符串长度:
服务器发送代码修改:
char encPubKey_First[BUFSIZE]; char encPubKey_Second[BUFSIZE]; // 使用_snprintf避免缓冲区溢出,保证写入不超过数组大小 _snprintf(encPubKey_First, BUFSIZE, "%u", enc.pub_Key_First); _snprintf(encPubKey_Second, BUFSIZE, "%u", enc.pub_Key_Second); // 仅发送实际字符串长度(包含终止符'\0',确保客户端能正确识别字符串结束) send(socket, encPubKey_First, strlen(encPubKey_First) + 1, 0); send(socket, encPubKey_Second, strlen(encPubKey_Second) + 1, 0);
额外代码问题修正建议
- 随机数生成问题:
Selectpq中每次调用都执行srand((unsigned)time(NULL)),短时间内多次调用会因时间戳相同生成重复随机数,建议将srand移到程序初始化阶段仅调用一次。 - 加密解密逻辑错误:
Enc函数中for (int k = 0; k == bufsize; k++)循环条件错误,永远不会执行,应改为k < bufsize。sum是类成员变量,加密解密前未重置为1,会导致累积计算错误,需在Enc和Decryption函数开头添加sum = 1;。Decryption函数的while (decrypt != bufsize)循环中decrypt未被更新,会导致死循环,需重新梳理解密逻辑。
内容的提问来源于stack exchange,提问作者LieuRabbit
相关产品推荐
相关产品推荐

