我需要建立一个不是很复杂但很有效率的东西。我没有太多的时间去调试。
我不知道这个方法是否足够强到可以加密要在Qr代码中显示的数据。
它将在Qt中编译。
#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;
}
}发布于 2019-11-01 11:08:40
我不知道博坦图书馆,所以我会坚持一些一般性的建议。
不要在全局范围内包括整个名称空间,特别是std命名空间。
在这个函数中,Qt的唯一使用是接受QString参数,我们只使用这些参数来转换为标准字符串。那么,为什么不通过接受文件名作为const std::string&来删除依赖项,并允许在非Qt项目中使用该函数呢?为了方便Qt的使用,我们可以单独提供一个(仅限于头的、微不足道的不可inlinable的)包装器来保持接口:
//encrypt.h
bool EncryptFile(const std::string& source, const std::string& destination);//encrypt-qt.h
bool EncryptFile(QString source, QString destination)
{ return EncryptFile(source.toStdString(), destination.toStdString(); }在传递到流的构造函数时,当然不需要使用c_str() -- std::string在那里很好(并且是预期的)。
我可能会进一步研究重载,并提供一个接受一对流的版本,这样我们就可以将其用于网络流或内存中的加密:
//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作为目标传递。我们可以解决这个问题:
return in && out;或者,我们可以安排流抛出异常:
in.exceptions(std::ifstream::failbit | std::ifstream::bad);
out.exceptions(std::ifstream::failbit | std::ifstream::bad);https://codereview.stackexchange.com/questions/231642
复制相似问题