【发布时间】:2014-04-26 19:47:48
【问题描述】:
我使用 Crypto++ 开发了一个 C++ 应用程序来加密信息并将文件存储在硬盘驱动器中。我使用完整性字符串来检查用户输入的密码是否正确。你能告诉我实现是否生成了一个安全文件吗?我是密码学世界的新手,我用我读过的东西制作了这个程序。
string integrity = "ImGood"
string plaintext = integrity + string("some text");
byte password[pswd.length()]; // The password is filled somewhere else
byte salt[SALT_SIZE]; // SALT_SIZE is 32
byte key[CryptoPP::AES::MAX_KEYLENGTH];
byte iv[CryptoPP::AES::BLOCKSIZE];
CryptoPP::AutoSeededRandomPool rnd;
rnd.GenerateBlock(iv, CryptoPP::AES::BLOCKSIZE);
rnd.GenerateBlock(salt, SALT_SIZE);
CryptoPP::PKCS5_PBKDF2_HMAC<CryptoPP::SHA512> gen;
gen.DeriveKey(key, CryptoPP::AES::MAX_KEYLENGTH, 32,
password, pswd.length(),
salt, SALT_SIZE,
256);
CryptoPP::StringSink* sink = new CryptoPP::StringSink(cipher);
CryptoPP::Base64Encoder* base64_enc = new CryptoPP::Base64Encoder(sink);
CryptoPP::CFB_Mode<CryptoPP::AES>::Encryption cfb_encryption(key, CryptoPP::AES::MAX_KEYLENGTH, iv);
CryptoPP::StreamTransformationFilter* aes_enc = new CryptoPP::StreamTransformationFilter(cfb_encryption, base64_enc);
CryptoPP::StringSource source(plaintext, true, aes_enc);
sstream out;
out << iv << salt << cipher;
然后将字符串流“out”中的信息写入文件。另一件事是我不知道派生函数中的“目的”参数是什么意思,我猜它是密钥的所需长度所以我输入了 32,但我不确定也找不到Crypto++ 手册中有关它的任何内容。
感谢指出的任何意见、建议或错误。
非常感谢您。
【问题讨论】:
-
乍一看,你的“完整性”检查完全被破坏了(它只保护了每个 AFAICT 块的前六个字节的完整性,即使这样也只是很弱)。使用经过身份验证的密码模式(例如,GCM、EAX、CCFB)或派生第二个密钥(这就是“目的”参数的用途;允许您从相同的输入生成多个用于不同目的的密钥)并使用它来计算密文和 IV 上的 HMAC。
-
非常感谢斯蒂芬。我认为如果完整性字符串被正确解密,那么整个消息就意味着密码是正确的。但我会阅读身份验证和您提到的那些模式。最后,如果我将目的设置为 32,代码会生成密钥编号 32?再次感谢。
-
purpose参数的值是完全任意的,只要它在你使用它的任何上下文中都是一致的。我很好奇:究竟是什么让你相信你的方法将确保密文的完整性? -
我想我错误地解释了完整性字符串的含义。我用它来查看用户是否写了正确的密码,如果密码正确,那么解密后的明文将是“ImGood”+“要安全的文本”。如果与该字符串对应的字节不等于“ImGood”,则密码错误。目前我不知道验证密码的方法,但我仍在阅读它。感谢您花时间回答。
-
这个问题似乎跑题了,因为它要求进行代码审查,应该移到 codereview.stackexchange.com 而不是这里。