首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >使用FileSource和FileSink将AES IV转换成文件

使用FileSource和FileSink将AES IV转换成文件
EN

Stack Overflow用户
提问于 2020-09-04 09:35:48
回答 1查看 238关注 0票数 2

我需要用crypto++加密大文件(多GB)。我设法找到了一个文档示例,该文档帮助我创建了以下两个函数:

代码语言:javascript
运行
复制
bool AESEncryptFile(const std::string& clearfile, const std::string& encfile, const std::string& key) {
    
    try {
        byte iv[CryptoPP::AES::BLOCKSIZE] = {};
        CryptoPP::CBC_Mode<CryptoPP::AES>::Encryption encryptor;
        encryptor.SetKeyWithIV((unsigned char*)key.c_str(), CryptoPP::AES::DEFAULT_KEYLENGTH, iv);

        CryptoPP::StreamTransformationFilter filter(encryptor);

        CryptoPP::FileSource source(clearfile.c_str(), false);
        CryptoPP::FileSink sink(encfile.c_str());

        source.Attach(new CryptoPP::Redirector(filter));
        filter.Attach(new CryptoPP::Redirector(sink));

        const CryptoPP::word64 BLOCK_SIZE = 4096;
        CryptoPP::word64 processed = 0;

        while (!EndOfFile(source) && !source.SourceExhausted()) {
            source.Pump(BLOCK_SIZE);
            filter.Flush(false);
            processed += BLOCK_SIZE;
        }

        filter.MessageEnd();
        return true;
    } catch (const CryptoPP::Exception& ex) {
        return false;
    }
    
}

bool AESDecryptFile(const std::string& encfile, const std::string& clearfile, const std::string& key) {
    
    try {
        byte iv[CryptoPP::AES::BLOCKSIZE] = {};
        CryptoPP::CBC_Mode<CryptoPP::AES>::Decryption decryptor;
        decryptor.SetKeyWithIV((unsigned char*)key.c_str(), CryptoPP::AES::DEFAULT_KEYLENGTH, iv);

        CryptoPP::StreamTransformationFilter filter(decryptor);

        CryptoPP::FileSource source(encfile.c_str(), false);
        CryptoPP::FileSink sink(clearfile.c_str());

        source.Attach(new CryptoPP::Redirector(filter));
        filter.Attach(new CryptoPP::Redirector(sink));

        const CryptoPP::word64 BLOCK_SIZE = 4096;
        CryptoPP::word64 processed = 0;

        while (!EndOfFile(source) && !source.SourceExhausted()) {
            source.Pump(BLOCK_SIZE);
            filter.Flush(false);
            processed += BLOCK_SIZE;
        }
.
        filter.MessageEnd();
        return true;
    } catch (const CryptoPP::Exception& ex) {
        return false;
    }
}

效果很好。在8GB文件上,我使用的内存非常少。但是正如您所看到的,IV是硬编码的(目前为空),我想:

  • 在加密时,将其作为文件的结尾.
  • 在解密时:从文件中获取IV以插入解密器.

是否有一种使用crypto++的方法,或者我应该在enc/解密过程之后/之前手动处理它?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-09-07 08:51:47

感谢所有不同的评论,这里是我设法做到的。正如@Sam Mason建议的那样,我将iv放在文件的开头:

因此,在开始加密之前,我把iv放在文件的开头:

代码语言:javascript
运行
复制
CryptoPP::ArraySource(iv, sizeof(iv), true,
    new CryptoPP::Redirector(sink)
);
// Encrypt

在解密的时候,我会像这样拿回静脉注射:

代码语言:javascript
运行
复制
unsigned char iv[CryptoPP::AES::BLOCKSIZE];
CryptoPP::ArraySink ivSink(iv, sizeof(iv));
source.Attach(new CryptoPP::Redirector(ivSink));
source.Pump(CryptoPP::AES::BLOCKSIZE);
// Decrypt

未来读者注意:不要使用空的IV,比如在我的操作中显示,而是随机生成一个,例如:

代码语言:javascript
运行
复制
CryptoPP::AutoSeededRandomPool prng;
unsigned char iv[CryptoPP::AES::BLOCKSIZE];
prng.GenerateBlock(iv, sizeof(iv));
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/63738572

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档