2013-02-22 51 views
1

我是新的cryptopp,我嘗試加密和解密文件中的文本。 我送花兒給人收到內存位置0x0012efe4此錯誤CryptoPP :: InvalidCiphertext只是這些行後:InvalidCiphertext excpetion

CryptoPP::StreamTransformationFilter stfDecryptor(cbcDecryption, new CryptoPP::StringSink(decryptedtext)); 
stfDecryptor.Put(reinterpret_cast<const unsigned char*>(ciphertext.c_str()), ciphertext.length()); 
stfDecryptor.MessageEnd(); 

加密/解密代碼:

BOOL Encryption() 
{ 
    // Key and IV setup 
    byte key[ CryptoPP::AES::DEFAULT_KEYLENGTH ], iv[ CryptoPP::AES::BLOCKSIZE ]; 
    memset(key, 0x00, CryptoPP::AES::DEFAULT_KEYLENGTH); 
    memset(iv, 0x00, CryptoPP::AES::BLOCKSIZE); 

    HW_PROFILE_INFO hwProfileInfo; 
    GetCurrentHwProfile(&hwProfileInfo); 

    (hwProfileInfo.szHwProfileGuid, strlen(hwProfileInfo.szHwProfileGuid), key);  
    (hwProfileInfo.szHwProfileGuid, strlen(hwProfileInfo.szHwProfileGuid), iv); 

    // String and Sink setup 
    string STRING; 
    ifstream infile; 
    infile.open ("test2.txt"); 

    getline(infile,STRING, '\0'); // Saves the line in STRING. 
    char cFilm[1000]; 
    strcpy(cFilm,STRING.c_str()); 
    infile.close(); 

    std::string plaintext = cFilm; 
    std::string ciphertext; 
    std::string decryptedtext; 

    // Dump Plain Text 
    std::cout << "Plain Text (" << plaintext.size() << " bytes)" << std::endl; 
    std::cout << plaintext; 
    std::cout << std::endl << std::endl; 

    // Create Cipher Text 
    CryptoPP::AES::Encryption aesEncryption(key, CryptoPP::AES::DEFAULT_KEYLENGTH); 
    CryptoPP::CBC_Mode_ExternalCipher::Encryption cbcEncryption(aesEncryption, iv); 
    CryptoPP::StreamTransformationFilter stfEncryptor(cbcEncryption, new CryptoPP::StringSink(ciphertext)); 
    stfEncryptor.Put(reinterpret_cast<const unsigned char*>(plaintext.c_str()), plaintext.length() + 1); 
    stfEncryptor.MessageEnd(); 

    // Dump Cipher Text 
    ofstream write ("test2a.txt", ios::out | ios::binary); 
    int at = ciphertext.length()+ 1; 
    write.write(ciphertext.c_str(),at); 
    write.close(); 
    ciphertext.erase(); 

    remove("test2.txt"); 
    rename("test2a.txt","c:\\test2.txt"); 

    return 0; 
} 

BOOL Decryption() 
{ 
    // Key and IV setup 
    byte key[ CryptoPP::AES::DEFAULT_KEYLENGTH ], iv[ CryptoPP::AES::BLOCKSIZE ]; 
    memset(key, 0x00, CryptoPP::AES::DEFAULT_KEYLENGTH); 
    memset(iv, 0x00, CryptoPP::AES::BLOCKSIZE); 

    HW_PROFILE_INFO hwProfileInfo; 
    GetCurrentHwProfile(&hwProfileInfo); 

    // String and Sink setup 
    string STRING2; 
    ifstream infile2; 
    infile2.open ("test2.txt",ios::binary); 

    getline(infile2,STRING2, '\0'); // Saves the line in STRING. 
    char cFilm2[1000]; 
    strcpy(cFilm2,STRING2.c_str()); 
    infile2.close(); 

    std::string ciphertext (cFilm2); 
    std::string decryptedtext; 

    // Decrypt 
    CryptoPP::AES::Decryption aesDecryption(key, CryptoPP::AES::DEFAULT_KEYLENGTH); 
    CryptoPP::CBC_Mode_ExternalCipher::Decryption cbcDecryption(aesDecryption, iv); 

    CryptoPP::StreamTransformationFilter stfDecryptor(cbcDecryption, new CryptoPP::StringSink(decryptedtext)); 
    stfDecryptor.Put(reinterpret_cast<const unsigned char*>(ciphertext.c_str()), ciphertext.length()); 
    stfDecryptor.MessageEnd(); 

    // Dump Decrypted Text 
    ofstream write ("test2a.txt", ios::out | ios::binary); 
    write << decryptedtext; 
    write.close(); 
    decryptedtext.erase(); 

    remove("test2.txt"); 
    rename("test2a.txt","test2.txt"); 

    return 0; 
} 

任何人知道如何解決這個問題?

回答

3

您的主要問題似乎是在使用getline'\0'定界符在Decryption()。如果Encryption()中的純文本不包含空字符,則這可能對Encryption()中的純文本起作用,但密文很可能在整個過程中充斥着'\0'

看起來好像您已經正確識別出加密文件包含二進制數據,但您需要像這樣讀取它,例如,使用std::ifstream::readstd::istreambuf_iterator

我已經更新了下面的示例代碼:

#include "windows.h" 

#include <algorithm> // for std::copy 
#include <fstream> 
#include <iostream> 
#include <iterator> // for std::istreambuf_iterator 
#include <string> 

#ifdef _MSC_VER 
# pragma warning(push) 
# pragma warning(disable: 4100 4127 4189 4244) 
#endif 
#include "cryptopp/aes.h" 
#include "cryptopp/config.h" 
#include "cryptopp/files.h" 
#include "cryptopp/filters.h" 
#include "cryptopp/modes.h" 
#ifdef _MSC_VER 
# pragma warning(pop) 
#endif 

namespace { 
const std::string original_file("original.txt"); 
const std::string encrypted_file("encrypted.txt"); 
const std::string decrypted_file("decrypted.txt"); 
const int key_size(CryptoPP::AES::DEFAULT_KEYLENGTH); 
const int iv_size(CryptoPP::AES::BLOCKSIZE); 
} 

void GetKeyAndIv(byte* key, byte* iv) { 
    HW_PROFILE_INFOA profile; 
    GetCurrentHwProfileA(&profile); 
    char* guid(profile.szHwProfileGuid); 
    assert(std::char_traits<char>::length(guid) >= key_size + iv_size); 
    // Assign first 'key_size' chars of GUID to 'key' 
    std::copy(guid, guid + key_size, key); 
    // Assign next 'iv_size' chars of GUID to 'iv' 
    std::copy(guid + key_size, guid + key_size + iv_size, iv); 
}; 

void Encrypt() { 
    // Initialise the key and IV 
    byte key[key_size] = {0}, iv[iv_size] = {0}; 
    GetKeyAndIv(key, iv); 

    // Read the file contents to a string and output to cout. Safest to read 
    // contents as binary data, although non-printable characters shouldn't be 
    // output to cout. 
    std::ifstream infile(original_file.c_str(), std::ios::binary); 
    const std::string plaintext((std::istreambuf_iterator<char>(infile)), 
           std::istreambuf_iterator<char>()); 
    infile.close(); 
    std::cout << "Plain Text (" << plaintext.size() << " bytes)\n" 
      << plaintext << "\n\n"; 

    // Encrypt 
    CryptoPP::AES::Encryption cipher(key, key_size); 
    CryptoPP::CBC_Mode_ExternalCipher::Encryption encryption(cipher, iv); 
    std::string cipher_text; 
    CryptoPP::StreamTransformationFilter filter(encryption, 
     new CryptoPP::StringSink(cipher_text)); 
    filter.Put(reinterpret_cast<const byte*>(plaintext.c_str()), plaintext.size()); 
    filter.MessageEnd(); 

    // Dump cipher text 
    std::ofstream outfile(encrypted_file.c_str(), std::ios::binary); 
    outfile.write(cipher_text.c_str(), cipher_text.size()); 
    outfile.close(); 
} 

void Decrypt() { 
    // Initialise the key and IV 
    byte key[key_size] = {0}, iv[iv_size] = {0}; 
    GetKeyAndIv(key, iv); 

    // Read the encrypted file contents to a string as binary data. 
    std::ifstream infile(encrypted_file.c_str(), std::ios::binary); 
    const std::string cipher_text((std::istreambuf_iterator<char>(infile)), 
           std::istreambuf_iterator<char>()); 
    infile.close(); 

    // Decrypt 
    CryptoPP::AES::Decryption cipher(key, key_size); 
    CryptoPP::CBC_Mode_ExternalCipher::Decryption decryption(cipher, iv); 
    std::string decrypted_test; 
    CryptoPP::StreamTransformationFilter filter(decryption, 
     new CryptoPP::StringSink(decrypted_test)); 
    filter.Put(reinterpret_cast<const byte*>(cipher_text.c_str()), 
      cipher_text.size()); 
    filter.MessageEnd(); 

    // Dump decrypted text 
    std::ofstream outfile(decrypted_file.c_str(), std::ios::binary); 
    outfile.write(decrypted_test.c_str(), decrypted_test.size()); 
    outfile.close(); 
} 

int main() { 
    try { 
    Encrypt(); 
    Decrypt(); 
    } 
    catch(const CryptoPP::Exception& exception) { 
    std::cout << "Caught exception: " << exception.what() << '\n'; 
    return -1; 
    } 
    return 0; 
} 

一個更簡單的選擇是使用CryptoPP的FileSourceFileSink類,以避免讀/手寫文件:

void Encrypt() { 
    byte key[key_size] = {0}, iv[iv_size] = {0}; 
    GetKeyAndIv(key, iv); 
    CryptoPP::CBC_Mode<CryptoPP::AES>::Encryption encryption; 
    encryption.SetKeyWithIV(key, key_size, iv, iv_size); 
    CryptoPP::FileSource file_source(original_file.c_str(), true, 
    new CryptoPP::StreamTransformationFilter(encryption, 
     new CryptoPP::FileSink(encrypted_file.c_str()))); 
} 

void Decrypt() { 
    byte key[key_size] = {0}, iv[iv_size] = {0}; 
    GetKeyAndIv(key, iv); 
    CryptoPP::CBC_Mode<CryptoPP::AES>::Decryption decryption; 
    decryption.SetKeyWithIV(key, key_size, iv, iv_size); 
    CryptoPP::FileSource file_source(encrypted_file.c_str(), true, 
    new CryptoPP::StreamTransformationFilter(decryption, 
     new CryptoPP::FileSink(decrypted_file.c_str()))); 
} 
+0

我欠你一杯啤酒! 謝謝! – TrockFOx 2013-02-24 19:49:26

+0

好吧,威士忌更多我的事...但啤酒會在一個捏! :-)很高興它有幫助。 – Fraser 2013-02-24 22:13:47

+0

您應該將Fraser的答案標記爲解決方案,以便訪問該頁面的其他人知道它的正確性。 – jww 2013-10-02 08:05:06

相關問題