C++通过fstream传输RSA加密消息后RSA_private_decrypt解密失败问题咨询
核心原因
- RSA加密后的结果是二进制数据,其中会随机出现
\0(ASCII空字符),你全程用字符串操作、文本模式读写流的逻辑完全不适用二进制数据,你做的strcmp、cout校验都是无效的,你以为内容一致实际上数据已经被截断/转义修改了。
具体错误点
- 流用了默认文本模式:
fstream默认以文本模式打开,Windows下会自动转义换行符(0x0A和0x0D0A互转),直接修改二进制数据的原始值。 - 字符串操作函数截断数据:
strcpy、strcmp都是遇到\0就停止执行,加密数据中间只要出现\0,后面的内容根本不会被拷贝、也不会被strcmp对比,你拿到的回传数据实际上是缺了后半段的,cout打印字符串同样是遇到\0就终止,所以你肉眼看内容是一致的。 - 用
<<运算符读写二进制数据:<<运算符是为字符串设计的,传入二进制的char*会自动按字符串逻辑处理,碰到\0就停止写入/读取,不能完整传输全部字节。
修复方案
- 所有涉及加密数据读写的流都指定二进制模式打开:
// 写文件 ofstream pipe; pipe.open("thePipe", ios::binary); // 读文件 ifstream in("thePipe", ios::binary);
- 用字节读写接口替代字符串操作:
- 写数据时按RSA密钥长度写完整字节:
pipe.write(encryptedMSG, RSA_size(publicRSA)); - 读数据时按RSA密钥长度读满字节:
in.read(receivedEncryptionMSG, RSA_size(publicRSA));
- 校验数据用内存对比函数,不要用
strcmp:
// 对比两个缓冲区前RSA_size(publicRSA)个字节是否完全一致 if (memcmp(encryptedMSG, receivedEncryptionMSG, RSA_size(publicRSA)) == 0) { // 才是真的内容一致 }
- 不要用
strcpy拷贝二进制数据,改用memcpy,长度指定为RSA密钥长度。
修复后再运行解密即可正常工作。
内容的提问来源于stack exchange,提问作者Avian fly
相关产品推荐
相关产品推荐

