使用Crypto+解密时,原始文本末尾的Gargage冗余字符+; 我使用Cito T++,CTR模式,对C++中的文本进行加密和解密。一切似乎都运转了99%。加密成功后,解密也会返回原始文本,但我在解密文本的末尾提供了一些额外的随机垃圾冗余文本,如“ð”。每次我运行代码时,都会随机生成这个额外的部分。我的代码有问题吗
使用Crypto+解密时,原始文本末尾的Gargage冗余字符+; 我使用Cito T++,CTR模式,对C++中的文本进行加密和解密。一切似乎都运转了99%。加密成功后,解密也会返回原始文本,但我在解密文本的末尾提供了一些额外的随机垃圾冗余文本,如“ð”。每次我运行代码时,都会随机生成这个额外的部分。我的代码有问题吗,c++,encryption,crypto++,C++,Encryption,Crypto++,将字符串加密为字符串 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 StreamTransform
将字符串加密为字符串
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;
}
}
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;
}
上面的换行解密字符串函数
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;
}
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;
}
我的测试脚本很简单。阅读some.txt内容(“我爱你”),将其写入s1.txt以检查阅读是否正确。加密、解密,然后将恢复的文本写入另一个文件(d1.txt)
只需分配writeable的长度=密码的长度。将终止符设置为
writeble[len]
,这在出现缓冲区溢出和未终止字符串等情况时很容易发生。如果我们查看您的encrypt
函数,就会发现缓冲区溢出:
len = cipher.size() + 1;
char * writable = new char[len];
std::copy(cipher.begin(), cipher.end(), writable);
writable[len] = '\0';
请参见此处分配的len
字节,其中len
比cipher
大一个。但是当您终止字符串时,您正在使用len
来索引超出范围的内容
应该使用
len-1
或cipher.size()
作为终止符索引。当出现缓冲区溢出和未终止字符串等情况时,往往会发生这种情况。如果我们查看您的encrypt
函数,就会发现缓冲区溢出:
len = cipher.size() + 1;
char * writable = new char[len];
std::copy(cipher.begin(), cipher.end(), writable);
writable[len] = '\0';
请参见此处分配的len
字节,其中len
比cipher
大一个。但是当您终止字符串时,您正在使用len
来索引超出范围的内容
您应该使用len-1
或cipher.size()
作为终止符索引
您还可以避免加密字符串
和解密字符串
以及额外的副本。我将向您展示加密
,解密
类似
char* encrypt(char * plainText, byte key[], int sizeKey, byte iv[], int sizeIV, long &len)
{
const unsigned long plainTextLen = len; len = 0;
const unsigned long extraLen = plainTextLen+16;
ArraySource source(plainText, plainTextLen, false);
unique_ptr<char[]> writable(new char[extraLen]);
ArraySink sink(writable, extraLen);
CTR_Mode< AES >::Encryption enc;
enc.SetKeyWithIV(key, sizeKey, iv, sizeIV);
source.Detach(new StreamTransformationFilter(enc, new Redirector(sink)));
source.PumpAll();
len = sink.TotalPutLength();
return writable.release();
}
char*加密(char*明文、字节密钥[]、int-sizeKey、byte-iv[]、int-sizeIV、long&len)
{
常量无符号长明文len=len;len=0;
const unsigned long extraLen=plainTextLen+16;
ArraySource源(纯文本、纯文本、假);
唯一可写(新字符[extraLen]);
阵列链路接收器(可写,外部);
CTR_模式::加密enc;
enc.SetKeyWithIV(键,sizeKey,iv,sizeIV);
分离(新的StreamTransformationFilter(enc,新的重定向器(接收器));
source.PumpAll();
len=sink.TotalPutLength();
返回writable.release();
}
我没有编译并运行它,因此您必须清除上面代码中的编译器问题。它们都应该是次要的,比如转换和转换
您通常不需要担心NULL
;只需使用ptr
和len
。您可以使用string recovered=string(ptr,len)从解密的密文创建std::string
代码><需要时,code>std::string
将生成一个NULL
,但通常不需要
Detach
不是打字错误。您可以使用它来附加
新过滤器和删除
以前的过滤器。您可以使用它来避免内存泄漏
您还可以避免加密字符串
和解密字符串
以及额外的副本。我将向您展示加密
,解密
类似
char* encrypt(char * plainText, byte key[], int sizeKey, byte iv[], int sizeIV, long &len)
{
const unsigned long plainTextLen = len; len = 0;
const unsigned long extraLen = plainTextLen+16;
ArraySource source(plainText, plainTextLen, false);
unique_ptr<char[]> writable(new char[extraLen]);
ArraySink sink(writable, extraLen);
CTR_Mode< AES >::Encryption enc;
enc.SetKeyWithIV(key, sizeKey, iv, sizeIV);
source.Detach(new StreamTransformationFilter(enc, new Redirector(sink)));
source.PumpAll();
len = sink.TotalPutLength();
return writable.release();
}
char*加密(char*明文、字节密钥[]、int-sizeKey、byte-iv[]、int-sizeIV、long&len)
{
常量无符号长明文len=len;len=0;
const unsigned long extraLen=plainTextLen+16;
ArraySource源(纯文本、纯文本、假);
唯一可写(新字符[extraLen]);
阵列链路接收器(可写,外部);
CTR_模式::加密enc;
enc.SetKeyWithIV(键,sizeKey,iv,sizeIV);
分离(新的StreamTransformationFilter(enc,新的重定向器(接收器));
source.PumpAll();
len=sink.TotalPutLength();
返回writable.release();
}
我没有编译并运行它,因此您必须清除上面代码中的编译器问题。它们都应该是次要的,比如转换和转换
您通常不需要担心NULL
;只需使用ptr
和len
。您可以使用string recovered=string(ptr,len)从解密的密文创建std::string
代码><需要时,code>std::string
将生成一个NULL
,但通常不需要
Detach
不是打字错误。您可以使用它来附加
新过滤器和删除
以前的过滤器。您可以使用它来避免内存泄漏。谢谢您的回答。我做了两个更改:第一,allocate writeable=new char[len];第二,可写[len]='\0'。它现在起作用了:)谢谢你的回答。我做了两个更改:第一,allocate writeable=new char[len];第二,可写[len]='\0'。它现在工作:)我用Visual C++测试你的加密()函数,在AraySink接收器(可写,Exelaln)中出现语法错误;因为可写是char[],当sink()需要字节*type@Andiana-“我没有编译并运行它,因此您必须清除上面代码中的编译器问题。它们都应该是次要的,比如转换和强制转换”。将字符*
转换为字节*
;然后将const char*
转换为const byte*
。我对unique\u ptr有点困惑,它似乎是最好的解决方案,而不是char*或string,但我不知道在这种情况下如何使用它。我是否使用writeble.get()获取了它的数据?@Andiana-我很抱歉,我一直试图提供的帮助没有帮助。在继续使用加密+库之前,也许你应该了解更多关于C++的内容。我用VisualC++来测试你的加密()函数,在AraySink接收器(可写,Exelaln)中出现语法错误;因为可写是char[],当sink()需要字节*type@Andia
char* encrypt(char * plainText, byte key[], int sizeKey, byte iv[], int sizeIV, long &len)
{
const unsigned long plainTextLen = len; len = 0;
const unsigned long extraLen = plainTextLen+16;
ArraySource source(plainText, plainTextLen, false);
unique_ptr<char[]> writable(new char[extraLen]);
ArraySink sink(writable, extraLen);
CTR_Mode< AES >::Encryption enc;
enc.SetKeyWithIV(key, sizeKey, iv, sizeIV);
source.Detach(new StreamTransformationFilter(enc, new Redirector(sink)));
source.PumpAll();
len = sink.TotalPutLength();
return writable.release();
}