密文长度不是 cryptopp 中块大小的倍数
ciphertext length is not a multiple of block size in cryptopp
我的程序可以将文本加密并保存在文件中,并在从文件中获取密文后进行解密。
但我一直收到此错误
terminate called after throwing an instance of 'CryptoPP::InvalidCiphertext'
what(): StreamTransformationFilter: ciphertext length is not a multiple of block size
从文件中读取数据时,我得到的文件大小为密文长度,但内容大小较小,这可能是错误的。
代码:
std::string key = "0123456789abcdef";
std::string plaintext = "name macmilan age 24 ciy bonn country germany";
std::string ciphertext;
std::string decryptedtext;
CryptoPP::AES::Encryption aesEncryption((byte *)key.c_str(), CryptoPP::AES::DEFAULT_KEYLENGTH);
CryptoPP::ECB_Mode_ExternalCipher::Encryption cbcEncryption( aesEncryption);
CryptoPP::StreamTransformationFilter stfEncryptor(cbcEncryption, new CryptoPP::StringSink( ciphertext ) );
stfEncryptor.Put( reinterpret_cast<const unsigned char*>( plaintext.c_str() ), plaintext.length() + 1 );
stfEncryptor.MessageEnd();
CryptoPP::AES::Decryption aesDecryption((byte *)key.c_str(), CryptoPP::AES::DEFAULT_KEYLENGTH);
CryptoPP::ECB_Mode_ExternalCipher::Decryption cbcDecryption( aesDecryption);
std::cout << "ciphertext Text:"<<ciphertext.c_str()<<"length"<<ciphertext.length()<< std::endl;
FILE *ptr = fopen("temp.txt", "w");
if(ptr){
fprintf(ptr, "%s",ciphertext.c_str());
fclose(ptr);
ptr = NULL;
}
ptr = fopen("temp.txt", "r");
if(ptr){
fseek(ptr, 0, SEEK_END);
size_t size = ftell(ptr);
std::cout << "file size"<<size<< std::endl;
char* temp = new char[size];
rewind(ptr);
fscanf(ptr,"%s",temp);
ciphertext = temp;
delete[] temp;
ptr = NULL;
}
std::cout << "ciphertext Text:"<<ciphertext.c_str()<<"length"<<ciphertext.length() << std::endl;
try{
CryptoPP::StreamTransformationFilter stfDecryptor(cbcDecryption, new CryptoPP::StringSink( decryptedtext ) );
stfDecryptor.Put( reinterpret_cast<const unsigned char*>( ciphertext.c_str() ), ciphertext.size() );
stfDecryptor.MessageEnd();
}
catch(CryptoPP::Exception &e)
{
std::cout << "Decrypted Text:"<<e.what();
}
std::cout << "Decrypted Text: " << std::endl;
std::cout << decryptedtext;
std::cout << std::endl << std::endl;
system("pause");
return 0;
输出:
ciphertext Text:î4¬■◄vqù┼Ä╢óΣ*₧z┐É;'!ìy─ªú√@╕╡Oh∙2♠ε\→ktáäì╘aÄδ▌length48
file size48
ciphertext Text:î4¬■◄vqù┼Ä╢óΣ*₧z┐É;'!ìy─ªú√@╕╡Oh∙2♠ε\length37
Decrypted Text:StreamTransformationFilter: ciphertext length is not a multiple o
f block sizeDecrypted Text:
name macmilan ag
您可能想以二进制模式读写文件 - 在调用 fopen
.
时使用 "wb" 和 "rb"
您可能还想使用 fwrite
和 fread
。 fscanf
将在空白处停止,这对您没有帮助。
读写二进制文件时,fopen
的mode
参数必须为"rb"
或"wb"
,否则文件中的不可打印字符可能被解释作为控制字符。在这里,您的数据中似乎有一个 Ctrl-Z(十六进制 0x1a
),它是文本文件中的文件结束标记。
在加密过程中,可能会出现各种字符,包括 null (0)。因此,当您在文件中写入加密字符串时,您也会写入 null。
当您检索加密值时,reader 获取空字符并假定该字符串已终止。所以它会更短。
为了解决问题,您必须使用 Base64 或 MD5 之类的编码,或者打开文件并以二进制模式读取
我的程序可以将文本加密并保存在文件中,并在从文件中获取密文后进行解密。
但我一直收到此错误
terminate called after throwing an instance of 'CryptoPP::InvalidCiphertext' what(): StreamTransformationFilter: ciphertext length is not a multiple of block size
从文件中读取数据时,我得到的文件大小为密文长度,但内容大小较小,这可能是错误的。
代码:
std::string key = "0123456789abcdef";
std::string plaintext = "name macmilan age 24 ciy bonn country germany";
std::string ciphertext;
std::string decryptedtext;
CryptoPP::AES::Encryption aesEncryption((byte *)key.c_str(), CryptoPP::AES::DEFAULT_KEYLENGTH);
CryptoPP::ECB_Mode_ExternalCipher::Encryption cbcEncryption( aesEncryption);
CryptoPP::StreamTransformationFilter stfEncryptor(cbcEncryption, new CryptoPP::StringSink( ciphertext ) );
stfEncryptor.Put( reinterpret_cast<const unsigned char*>( plaintext.c_str() ), plaintext.length() + 1 );
stfEncryptor.MessageEnd();
CryptoPP::AES::Decryption aesDecryption((byte *)key.c_str(), CryptoPP::AES::DEFAULT_KEYLENGTH);
CryptoPP::ECB_Mode_ExternalCipher::Decryption cbcDecryption( aesDecryption);
std::cout << "ciphertext Text:"<<ciphertext.c_str()<<"length"<<ciphertext.length()<< std::endl;
FILE *ptr = fopen("temp.txt", "w");
if(ptr){
fprintf(ptr, "%s",ciphertext.c_str());
fclose(ptr);
ptr = NULL;
}
ptr = fopen("temp.txt", "r");
if(ptr){
fseek(ptr, 0, SEEK_END);
size_t size = ftell(ptr);
std::cout << "file size"<<size<< std::endl;
char* temp = new char[size];
rewind(ptr);
fscanf(ptr,"%s",temp);
ciphertext = temp;
delete[] temp;
ptr = NULL;
}
std::cout << "ciphertext Text:"<<ciphertext.c_str()<<"length"<<ciphertext.length() << std::endl;
try{
CryptoPP::StreamTransformationFilter stfDecryptor(cbcDecryption, new CryptoPP::StringSink( decryptedtext ) );
stfDecryptor.Put( reinterpret_cast<const unsigned char*>( ciphertext.c_str() ), ciphertext.size() );
stfDecryptor.MessageEnd();
}
catch(CryptoPP::Exception &e)
{
std::cout << "Decrypted Text:"<<e.what();
}
std::cout << "Decrypted Text: " << std::endl;
std::cout << decryptedtext;
std::cout << std::endl << std::endl;
system("pause");
return 0;
输出:
ciphertext Text:î4¬■◄vqù┼Ä╢óΣ*₧z┐É;'!ìy─ªú√@╕╡Oh∙2♠ε\→ktáäì╘aÄδ▌length48
file size48
ciphertext Text:î4¬■◄vqù┼Ä╢óΣ*₧z┐É;'!ìy─ªú√@╕╡Oh∙2♠ε\length37
Decrypted Text:StreamTransformationFilter: ciphertext length is not a multiple o
f block sizeDecrypted Text:
name macmilan ag
您可能想以二进制模式读写文件 - 在调用 fopen
.
您可能还想使用 fwrite
和 fread
。 fscanf
将在空白处停止,这对您没有帮助。
读写二进制文件时,fopen
的mode
参数必须为"rb"
或"wb"
,否则文件中的不可打印字符可能被解释作为控制字符。在这里,您的数据中似乎有一个 Ctrl-Z(十六进制 0x1a
),它是文本文件中的文件结束标记。
在加密过程中,可能会出现各种字符,包括 null (0)。因此,当您在文件中写入加密字符串时,您也会写入 null。 当您检索加密值时,reader 获取空字符并假定该字符串已终止。所以它会更短。 为了解决问题,您必须使用 Base64 或 MD5 之类的编码,或者打开文件并以二进制模式读取