密文长度不是cryptopp中块大小的倍数

时间:2016-01-31 13:18:28

标签: c++ cryptography crypto++

我的程序可以加密文本并将其保存在文件中,并在从文件中获取后解密密文。

但我继续犯这个错误

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

3 个答案:

答案 0 :(得分:3)

在加密中,可能会出现各种字符,包括null(0)。因此,当您在文件中写入加密字符串时,您也会写入null。 当您检索加密值读取器获取空字符并假定该字符串已终止。所以会更短。 要解决此问题,您必须使用Base64或MD5等编码或打开文件并以二进制模式读取

答案 1 :(得分:1)

您可能希望以二进制模式读取和写入文件 - 使用&#34; wb&#34;和&#34; rb&#34;在致电fopen时。

您也可以使用fwritefreadfscanf将停留在无法帮助您的空白处。

答案 2 :(得分:1)

读取和写入二进制文件时,mode fopen参数必须为"rb""wb",否则文件中的不可打印字符可能会被解释为控件字符。这里看起来你的数据中有一个Ctrl-Z(十六进制0x1a),它是文本文件中的文件结束标记。