我用des加密后,对原始密文解密没有问题。
但是使用这两个函数
void MessageName2::setCiphertxt(const char * ciphertxt_var)
{
this->ciphertxt_var = ciphertxt_var;
}
const char * MessageName2::getCiphertxt() const
{
return ciphertxt_var.c_str();
}
原始数据我是通过随机数生成的,转为char[]后进行加密,对密文先用setCiphertxt(),再用解密函数对getCiphertxt()解密,测试五十次大概就会有一次出现问题。
比如,原始数据是21001839,解密后变成210018ßt,后面几位出现乱码,或者解密出来都是乱码。
加解密代码是网上找的,测试过是没有问题的。
纠结了好久,有没有大神知道是怎么回事?
void yxyDES2::EncryptData(char* _srcBytes,unsigned int keyN)
{
char szSrcBits[64] = {0};
char sz_IP[64] = {0};
char sz_Li[32] = {0};
char sz_Ri[32] = {0};
char sz_Final64[64] = {0};
Bytes2Bits(_srcBytes,szSrcBits,64);
//IP
InitialPermuteData(szSrcBits,sz_IP);
memcpy(sz_Li,sz_IP,32);
memcpy(sz_Ri,sz_IP + 32,32);
for(int i=0;i<16;i++)
{
FunctionF(sz_Li,sz_Ri,i,keyN);
}
//so D=LR
memcpy(sz_Final64,sz_Ri,32);
memcpy(sz_Final64 + 32,sz_Li,32);
//~IP
for(int j=0;j<64;j++)
{
szCiphertextRaw[j] = sz_Final64[IPR_Table[j]-1];
}
Bits2Bytes(szCiphertextInBytes,szCiphertextRaw,64);
}
void yxyDES2::DecryptData(char* _srcBytes,unsigned int keyN)
{
char szSrcBits[64] = {0};
char sz_IP[64] = {0};
char sz_Li[32] = {0};
char sz_Ri[32] = {0};
char sz_Final64[64] = {0};
Bytes2Bits(_srcBytes,szSrcBits,64);
//IP --- return is sz_IP
InitialPermuteData(szSrcBits,sz_IP);
//divide the 64 bits data to two parts
memcpy(sz_Ri,sz_IP,32); //exchange L to R
memcpy(sz_Li,sz_IP + 32,32); //exchange R to L
//16 rounds F and xor and exchange
for(int i=0;i<16;i++)
{
FunctionF(sz_Ri,sz_Li,15-i,keyN);
}
memcpy(sz_Final64,sz_Li,32);
memcpy(sz_Final64 + 32,sz_Ri,32);
// ~IP
for(int j=0;j<64;j++)
{
szPlaintextRaw[j] = sz_Final64[IPR_Table[j]-1];
}
Bits2Bytes(szPlaintextInBytes,szPlaintextRaw,64);
}
该回答引用ChatGPT
问题可能出在你的 setCiphertxt 函数上。在这个函数中,你将传入的 char* 类型指针直接赋值给了成员变量 ciphertxt_var,这个变量的类型是 std::string。然而,当你离开函数时,输入的 char* 可能已经被销毁了,而成员变量 ciphertxt_var 就指向了已经被释放的内存。这将导致 getCiphertxt 返回一个无效的指针,进而导致解密函数无法正常工作,可能会出现乱码等问题。
解决这个问题的一种方法是将 setCiphertxt 函数修改为:
void MessageName2::setCiphertxt(const char* ciphertxt_var, size_t length)
{
this->ciphertxt_var.assign(ciphertxt_var, length);
}
这个函数将输入的 char* 数组复制到成员变量 ciphertxt_var 中,确保了成员变量中保存的是一个有效的 std::string 对象,而不是指向已经被销毁的内存的指针。你可以在使用 setCiphertxt 函数时,将输入数组的长度也传递进去,以确保 std::string 对象中保存的字符串与输入数组中的内容一致。例如:
char plaintext[] = "21001839";
des.EncryptData(plaintext, 1);
char* ciphertext = des.GetCiphertextInBytes();
size_t ciphertext_length = strlen(ciphertext);
msg.setCiphertxt(ciphertext, ciphertext_length);
// 确认 msg.getCiphertxt() 返回了正确的字符串
const char* ciphertxt = msg.getCiphertxt();
std::cout << "ciphertext: " << ciphertxt << std::endl;
// 解密
des.DecryptData(ciphertext, 1);
char* plaintext2 = des.GetPlaintextInBytes();
// 确认解密结果正确
std::cout << "plaintext: " << plaintext2 << std::endl;
这样,就可以避免 setCiphertxt 函数中出现的问题,确保解密结果正确。