2016-11-19 73 views
0

这是加密大文件的Crypto ++ FileSource的代码。它的工作完美,但都在黑匣子中,并且不允许我在加密时将加密数据保存到字节数组中。我想知道下面的机制以保存临时数据。该文件似乎只提供界面,在FileSource Class Reference如何将加密的FileSource数据保存到字节数组?

EAX<Blowfish>::Encryption e1; 
e1.SetKeyWithIV(key, key.size(), iv, sizeof(iv)); 

FileSource fs1(ofilename.c_str(), true, 
    new AuthenticatedEncryptionFilter(e1, 
     new FileSink(efilename.c_str()))); 

希望有人可以告诉我的机制或某处我可以了解它的地方。

+0

不要使用河豚,使用AES(高级加密标准),河豚即使创作者使用AES现在。 – zaph

+0

是的。但它只是例如,我的问题是FileSource机制,而不是使用哪种算法。 – Andiana

+1

你必须学习流媒体。 – zaph

回答

0

... and doesn't allow me to save encrypted data to a byte array when encrypting. I want to know the mechanism beneath in order to save the temporary data.

其实我不清楚你想用临时数组做什么,所以下面的答案可能不正确。

有两种方法可以在数组中创建临时结果。首先是将文件加密成数组的串行操作,然后将数组写入磁盘。其次是同时创建阵列和加密文件的并行操作。

您不能使用C++ 11 std::array,因为在运行时已知数组的大小为而不是。您可以使用std::vector,并提供摘录。


串行

#include <fstream> 
#include <iostream> 
#include <string> 
#include <memory> 
using namespace std; 

#include "osrng.h" 
#include "eax.h" 
#include "modes.h" 
#include "blowfish.h" 
#include "filters.h" 
#include "files.h" 

using namespace CryptoPP; 

int main(int argc, char* argv[]) 
{ 
    SecByteBlock key(Blowfish::DEFAULT_KEYLENGTH), iv(Blowfish::BLOCKSIZE); 
    string ifilename("config.h"), ofilename("config.h.enc"); 

    memset(key, 0x00, key.size()); 
    memset(iv, 0x00, iv.size()); 

    EAX<Blowfish>::Encryption enc; 
    enc.SetKeyWithIV(key, key.size(), iv, sizeof(iv)); 

    ifstream strm(ifilename.c_str(), ios::in | ios::binary); 
    size_t len = strm.seekg(0, std::ios_base::end).tellg(); 
    strm.seekg(0, std::ios_base::beg); 

    cout << "Data size: " << len << ", tag size: " << enc.TagSize() << endl; 

    FileSource fs1(strm, false); 
    len += enc.TagSize(); 

    cout << "Expected encrypted data and tag size: " << len << endl; 
    len += Blowfish::BLOCKSIZE; 
    cout << "Overcommitted encrypted data and tag size: " << len << endl; 

    unique_ptr<byte[]> ptr(new byte[len]); 
    ArraySink as1(ptr.get(), len); 

    fs1.Detach(new AuthenticatedEncryptionFilter(enc, new Redirector(as1))); 
    fs1.PumpAll(); 

    len = as1.TotalPutLength(); 
    cout << "Encrypted data and tag size: " << as1.TotalPutLength() << endl; 

    ArraySource as2(ptr.get(), len, true, new FileSink(ofilename.c_str())); 

    return 0; 
} 

串行示例生产:

$ ./test.exe 
Data size: 38129, tag size: 8 
Expected encrypted data and tag size: 38137 
Overcommitted encrypted data and tag size: 38145 
Encrypted data and tag size: 38137 

$ ls -l config.* 
-rw-r--r--. 1 ... 38223 Nov 19 04:40 config.compat 
-rw-r--r--. 1 ... 38129 Nov 19 04:40 config.h 
-rw-r--r--. 1 ... 38137 Nov 19 06:03 config.h.enc 

并行

#include <fstream> 
#include <iostream> 
#include <string> 
#include <memory> 
using namespace std; 

#include "osrng.h" 
#include "eax.h" 
#include "modes.h" 
#include "blowfish.h" 
#include "filters.h" 
#include "files.h" 
#include "channels.h" 

using namespace CryptoPP; 

int main(int argc, char* argv[]) 
{ 
    SecByteBlock key(Blowfish::DEFAULT_KEYLENGTH), iv(Blowfish::BLOCKSIZE); 
    string ifilename("config.h"), ofilename("config.h.enc"); 

    memset(key, 0x00, key.size()); 
    memset(iv, 0x00, iv.size()); 

    EAX<Blowfish>::Encryption enc; 
    enc.SetKeyWithIV(key, key.size(), iv, sizeof(iv)); 

    ifstream strm(ifilename.c_str(), ios::in | ios::binary); 
    size_t len = strm.seekg(0, std::ios_base::end).tellg(); 
    strm.seekg(0, std::ios_base::beg); 

    // Overcommit 
    len += enc.TagSize() + Blowfish::BLOCKSIZE; 

    // The one and only source 
    FileSource fs1(strm, false); 

    // The first sink 
    FileSink fs2(ofilename.c_str(), true); 

    // The second sink 
    unique_ptr<byte[]> ptr(new byte[len]); 
    ArraySink as1(ptr.get(), len); 

    // The magic to output to both sinks 
    ChannelSwitch cs; 
    cs.AddDefaultRoute(as1); 
    cs.AddDefaultRoute(fs2); 

    fs1.Detach(new AuthenticatedEncryptionFilter(enc, new Redirector(cs))); 
    fs1.PumpAll(); 

    return 0; 
} 

平行示例生产:

$ ./test.exe 

$ ls -l config.* 
-rw-r--r--. 1 ... 38223 Nov 19 04:40 config.compat 
-rw-r--r--. 1 ... 38129 Nov 19 04:40 config.h 
-rw-r--r--. 1 ... 38137 Nov 19 06:02 config.h.enc 

的std ::矢量

代替:

unique_ptr<byte[]> ptr(new byte[len]); 
ArraySink as1(ptr.get(), len); 

您可以使用:

std::vector<byte> v; 
... 

v.resize(len); 
ArraySink as(&v[0], v.size()); 
... 

// Perform encryption 
fs.Detach(new AuthenticatedEncryptionFilter(enc, new Redirector(as))); 
fs.PumpAll(); 

// Resize now you know the size of ciphertext and tag 
v.resize(as.TotalPutLength()); 
+0

我用Visual C++ 2013运行了上面的代码,并且都给了我一个错误:abc.exe中的0x75F1A6F2未处理的异常:Microsoft C++异常:内存位置0x0116E5A0处的CryptoPP :: FileStore :: ReadErr。这是一个平台相关的错误?我在Ubuntu上试过了,得到了同样的错误CryptoPP :: FileStore :: ReadErr – Andiana

+0

@Andiana - 我很抱歉,我一直试图提供的帮助没有帮助。也许你应该在继续使用Crypto ++库之前了解更多关于C++的知识。 – jww