首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用Botan库加密文件

使用Botan库加密文件
EN

Code Review用户
提问于 2019-10-31 23:46:47
回答 1查看 840关注 0票数 0

我需要建立一个不是很复杂但很有效率的东西。我没有太多的时间去调试。

我不知道这个方法是否足够强到可以加密要在Qr代码中显示的数据。

它将在Qt中编译。

代码语言:javascript
复制
    #include <botan/botan.h>
    #include <botan/aes.h>
    #include <botan/kdf.h>
    #include <botan/pbkdf2.h>
    #include <botan/hmac.h>
    #include <botan/sha160.h>

    using namespace std;
    using namespace Botan;

    // .....

    bool BotanWrapper::EncryptFile(QString Source, QString Destination)
    {
    try
    {
    //Setup the key derive functions
    PKCS5_PBKDF2 pbkdf2(new HMAC(new SHA_160));
    const u32bit PBKDF2_ITERATIONS = 8192;

    //Create the KEY and IV
    KDF* kdf = get_kdf("KDF2(SHA-1)");

    //Create the master key
    SecureVector<byte> mMaster = pbkdf2.derive_key(48, mPassword.toStdString(), &mSalt[0], mSalt.size(),PBKDF2_ITERATIONS).bits_of();
    SymmetricKey mKey = kdf->derive_key(32, mMaster, "salt1");
    InitializationVector mIV = kdf->derive_key(16, mMaster, "salt2");

    string inFilename = Source.toStdString();
    string outFilename = Destination.toStdString();
    std::ifstream in(inFilename.c_str(),std::ios::binary);
    std::ofstream out(outFilename.c_str(),std::ios::binary);

    Pipe pipe(get_cipher("AES-256/CBC/PKCS7", mKey, mIV,ENCRYPTION),new DataSink_Stream(out));
    pipe.start_msg();
    in >> pipe;
    pipe.end_msg();

    out.flush();
    out.close();
    in.close();

    return true;
   }
   catch(...)
   {
    return false;
    }
   }
EN

回答 1

Code Review用户

发布于 2019-11-01 11:08:40

我不知道博坦图书馆,所以我会坚持一些一般性的建议。

不要在全局范围内包括整个名称空间,特别是std命名空间。

在这个函数中,Qt的唯一使用是接受QString参数,我们只使用这些参数来转换为标准字符串。那么,为什么不通过接受文件名作为const std::string&来删除依赖项,并允许在非Qt项目中使用该函数呢?为了方便Qt的使用,我们可以单独提供一个(仅限于头的、微不足道的不可inlinable的)包装器来保持接口:

代码语言:javascript
复制
//encrypt.h
bool EncryptFile(const std::string& source, const std::string& destination);
代码语言:javascript
复制
//encrypt-qt.h
bool EncryptFile(QString source, QString destination)
{ return EncryptFile(source.toStdString(), destination.toStdString(); }

在传递到流的构造函数时,当然不需要使用c_str() -- std::string在那里很好(并且是预期的)。

我可能会进一步研究重载,并提供一个接受一对流的版本,这样我们就可以将其用于网络流或内存中的加密:

代码语言:javascript
复制
//encrypt.h
bool EncryptFile(std::istream& source, std::ostream& destination);

bool EncryptFile(const std::string& source, const std::string& destination);
{
    try {
        std::ifstream in(source, std::ios::binary);
        std::ofstream out(destination, std::ios::binary);
        return EncryptFile(in, out);
    } catch (...) {
        return false;
    }
}

为什么我们返回true,即使写入输出失败?例如,尝试将/dev/full作为目标传递。我们可以解决这个问题:

代码语言:javascript
复制
return in && out;

或者,我们可以安排流抛出异常:

代码语言:javascript
复制
    in.exceptions(std::ifstream::failbit | std::ifstream::bad);
    out.exceptions(std::ifstream::failbit | std::ifstream::bad);
票数 2
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/231642

复制
相关文章

相似问题

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