问题描述
我正在使用Crypto ++,CTR模式来加密和解密C ++中的文本。一切似乎都在99%。解密成功,解密也是给出原始文本,但是在解密文本的末尾,我给出了一些额外的随机垃圾冗余文本,如ð。这个额外的部分是每次运行代码时随机生成的。我的代码有问题吗?
将字符串加密到字符串
string encryptString(string plain,byte key [],int sizeKey,byte iv [],int sizeIV){
string cipher;
try {
CTR_Mode< AES> ::加密e
e.SetKeyWithIV(key,sizeKey,iv,sizeIV);
// StreamTransformationFilter根据需要删除
// padding。
StringSource s(plain,true,
new StreamTransformationFilter(e,
new StringSink(cipher)
)
);
#if 0
StreamTransformationFilter过滤器(e);
filter.Put((const byte *)plain.data(),plain.size());
filter.MessageEnd();
const size_t ret = filter.MaxRetrievable();
cipher.resize(ret);
filter.Get((byte *)cipher.data(),cipher.size());
#endif
return cipher;
}
catch(const CryptoPP :: Exception& e)
{
cerr< e.what()< ENDL;
返回NULL;
}
}
将一个加密的字符串解密到一个字符串
string decryptString(string cipher,byte key [],int sizeKey,byte iv [],int sizeIV){
string reco = ;
try {
CTR_Mode< AES> ::解密d
d.SetKeyWithIV(key,sizeKey,iv,sizeIV);
StringSource s(cipher,true,
new StreamTransformationFilter(d,
new StringSink(reco)
)
);
}
catch(const CryptoPP :: Exception& e)
{
cerr< e.what()< ENDL;
}
return reco;
}
上面加载encryptString函数。
char * encrypt(char * plainText,byte key [],int sizeKey,byte iv [],int sizeIV,long& len){
string cipher = encryptString(plainText,key,sizeKey,iv,sizeIV);
len = cipher.size()+ 1;
char * writable = new char [len];
std :: copy(cipher.begin(),cipher.end(),可写);
可写[len] ='\0'; //不要忘记终止0
返回可写;
}
包含上面的decryptString函数。
*
string ss(cipher,char, LEN);
long lengSS = ss.length();
string recover = decryptString(ss,key,sizeKey,iv,sizeIV);
char * writable = new char [recover.size()+ 1];
std :: copy(recover.begin(),recover.end(),可写);
writable [recover.size()] ='\0'; //不要忘记终止0
返回可写;
}
我的测试脚本很简单。阅读some.txt的内容(我爱你),写入s1.txt来检查阅读是否正确。加密,解密,然后将恢复的文本写入另一个文件(d1.txt)。
int main(int argc,char * argv [])
{
AutoSeededRandomPool prng;
byte key [AES :: DEFAULT_KEYLENGTH] = {'1','2','3','4','5','6','7' '1','2','3','4','5','6','7','8'};
//prng.GenerateBlock(key,sizeof(key));
byte iv [AES :: BLOCKSIZE] = {'8','7','6','5','4','3','2' '8','7','6','5','4','3','2','1'};
prng.GenerateBlock(iv,sizeof(iv));
long size = 0;
char * s1 = FileUtil :: readAllByte(some.txt);
//结果:s1.txt的内容是我爱你
long len = 0;
char * result1 = encrypt(s1,key,sizeof(key),iv,sizeof(iv),len);
//结果:result1是一串加密字符
cout<<< desc< ENDL;
char * restored1 = decrypt(result1,key,sizeof(key),iv,sizeof(iv),len);
//结果:restored1 =我爱你。一般来说,它具有我爱你X的形式
// X可以是任何垃圾聊天者,每次运行代码时,X是一个不同的
//字符。
}
根据接受答案,解决方案是:更新我的encrypt()像这样:
char * encrypt(char * plainText,byte key [],int sizeKey,byte iv [],int sizeIV,long & len){
string cipher = encryptString(plainText,key,sizeKey,iv,sizeIV);
FileUtil :: writeFile(ss1.txt,cipher,cipher.length());
len = cipher.size();
char * writable = new char [len];
std :: copy(cipher.begin(),cipher.end(),可写);
可写[len] ='\0'; //不要忘记终止0
FileUtil :: writeFile(w1.txt,可写,len);
返回可写;
}
只需分配可写的长度=密码的长度。将终结器设置为 writeble [len]
当您有缓冲区溢出和未终止的字符串时。如果我们查看您的加密
函数,我们看到缓冲区溢出:
len = cipher.size()+ 1;
char * writable = new char [len];
std :: copy(cipher.begin(),cipher.end(),可写);
可写[len] ='\0';
看到这里你分配了 len
len
大于 cipher
。但是当您终止字符串时,您正在使用 len
进行索引,这是超出范围的。
您应该使用 len-1
或 cipher.size()
作为终结者索引。
I am using Crypto++, CTR mode, to encrypt and decrypt text in C++. Everything seem to worked 99%. Ecrypting success, decrypting is give back the original text too, but I given some extra random garbage redundancy text like 'ð', at the end of the decrypted text. This extra part is random generated each time I run the code. Is there something wrong in my code?
Encrypt a string to a string
string encryptString(string plain, byte key[], int sizeKey, byte iv[], int sizeIV){
string cipher;
try{
CTR_Mode< AES >::Encryption e;
e.SetKeyWithIV(key, sizeKey, iv, sizeIV);
// The StreamTransformationFilter removes
// padding as required.
StringSource s(plain, true,
new StreamTransformationFilter(e,
new StringSink(cipher)
)
);
#if 0
StreamTransformationFilter filter(e);
filter.Put((const byte*)plain.data(), plain.size());
filter.MessageEnd();
const size_t ret = filter.MaxRetrievable();
cipher.resize(ret);
filter.Get((byte*)cipher.data(), cipher.size());
#endif
return cipher;
}
catch (const CryptoPP::Exception& e)
{
cerr << e.what() << endl;
return NULL;
}
}
Decrypt a ciphered string to a string
string decryptString(string cipher, byte key[], int sizeKey, byte iv[], int sizeIV){
string reco ="";
try{
CTR_Mode< AES >::Decryption d;
d.SetKeyWithIV(key, sizeKey, iv, sizeIV);
StringSource s(cipher, true,
new StreamTransformationFilter(d,
new StringSink(reco)
)
);
}
catch (const CryptoPP::Exception& e)
{
cerr << e.what() << endl;
}
return reco;
}
Wrap encryptString function above.
char* encrypt(char * plainText, byte key[], int sizeKey, byte iv[], int sizeIV, long &len){
string cipher = encryptString(plainText, key, sizeKey, iv, sizeIV);
len = cipher.size() + 1;
char * writable = new char[len];
std::copy(cipher.begin(), cipher.end(), writable);
writable[len] = '\0'; // don't forget the terminating 0
return writable;
}
Wrap decryptString function above.
char* decrypt(char * cipher, byte key[], int sizeKey, byte iv[], int sizeIV, long len){
string ss(cipher, len);
long lengSS = ss.length();
string recovered = decryptString(ss, key, sizeKey, iv, sizeIV);
char * writable = new char[recovered.size() + 1];
std::copy(recovered.begin(), recovered.end(), writable);
writable[recovered.size()] = '\0'; // don't forget the terminating 0
return writable;
}
My test script is simple. Read the some.txt content ("I love you"), write it to s1.txt to check if the reading is right. Encrypt, decrypt, then write the recovered text to another file (d1.txt).
int main(int argc, char* argv[])
{
AutoSeededRandomPool prng;
byte key[AES::DEFAULT_KEYLENGTH] = { '1', '2', '3', '4', '5', '6', '7', '8', '1', '2', '3', '4', '5', '6', '7', '8' };
//prng.GenerateBlock(key, sizeof(key));
byte iv[AES::BLOCKSIZE] = { '8', '7', '6', '5', '4', '3', '2', '1', '8', '7', '6', '5', '4', '3', '2', '1' };
prng.GenerateBlock(iv, sizeof(iv));
long size = 0;
char * s1 = FileUtil::readAllByte("some.txt");
//Result: s1.txt content is "I love you"
long len = 0;
char* result1 = encrypt(s1, key, sizeof(key), iv, sizeof(iv), len);
//Result: result1 is a bunch of ciphered characters
cout << "desc" << endl;
char* recovered1 = decrypt(result1, key, sizeof(key), iv, sizeof(iv), len);
//Result: recovered1="I love youð". Generally, it has form of "I love youX"
//X can be any garbage chatacter, and each time I run the code, X is one different
//character.
}
According to the accept answer, Solution is: updated my encrypt() like this:
char* encrypt(char * plainText, byte key[], int sizeKey, byte iv[], int sizeIV, long &len){
string cipher = encryptString(plainText, key, sizeKey, iv, sizeIV);
FileUtil::writeFile("ss1.txt", cipher, cipher.length());
len = cipher.size() ;
char * writable = new char[len];
std::copy(cipher.begin(), cipher.end(), writable);
writable[len] = '\0'; // don't forget the terminating 0
FileUtil::writeFile("w1.txt",writable, len);
return writable;
}
Just allocate writeable's length = cipher's length. Set the terminator at writeble[len]
That tends to happen when you have things like buffer overruns and unterminated strings. If we look at your encrypt
function we see a buffer overrun:
len = cipher.size() + 1;
char * writable = new char[len];
std::copy(cipher.begin(), cipher.end(), writable);
writable[len] = '\0';
See here you allocated len
bytes, where len
is one larger than cipher
. But when you terminate the string, you are using len
to index which is out-of-bounds.
You should either use len-1
or cipher.size()
for the terminator index.
这篇关于使用Crypto ++进行解密时,原始文本末尾的缩放冗余字符的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!