gpt4 book ai didi

c++ - 重新加密加密数据文件生成解密输出

转载 作者:太空宇宙 更新时间:2023-11-04 12:34:53 25 4
gpt4 key购买 nike

我使用 Crypto++ 库编写了加密函数,该函数在第一次完成文件加密时运行正确。如果再次传递相同的加密文件进行加密,则生成包含加密和解密数据的输出。

bool EncryptDataFile(const char* inputFile, const char* outputFile)
{
try
{
std::vector<byte> key = HexDecoding(PASSCODE);
std::vector<byte> iv = HexDecoding(INITIALIZATION_VECTOR);

GCM<AES>::Encryption encryptor;
encryptor.SetKeyWithIV(key.data(), key.size(), iv.data(), iv.size());

FileSource fs(inputFile, true,
new AuthenticatedEncryptionFilter(encryptor,
new FileSink(outputFile), false, TAG_SIZE));
}

catch(...)
{
return false;
}

return true;
}

输入.txt:

Privacy and Security

Output1.txt - 第一次加密输出:

{)ªei ?ñìCzN[hç&Ää€|Ùrñ½…
Ä

输入“Output1.txt”,输出“Output2.txt”-二次加密:

Privacy and Security]®Ÿwþñ úeS„£Fpä40WL ,ÈR¯M 

它揭示了原始数据。不确定这里缺少什么。

最佳答案

If the same encrypted file is passed again for encryption, generates the output which includes encrypted and decrypted data.

如果我解析正确,你在加密时说的是 m ≅ Enc(Enc(m)) 而不是 c = Enc(Enc(m))方案。这是您应避免设计自己的方案的原因之一。

这可能会在多种情况下发生,例如在重复使用 key 和 iv 时,在计数器模式下使用流密码或 block 密码。

您应该为每个消息或加密操作使用不同的安全上下文。无需手动操作,这意味着更改每个消息或加密操作的 key 或 iv。


std::vector<byte> key = HexDecoding(PASSCODE);
std::vector<byte> iv = HexDecoding(INITIALIZATION_VECTOR);

这可能是您的问题。您需要为每个消息或加密操作使用不同的安全上下文。


这里是你如何修复它。您使用 key 派生函数为每个加密派生不同的安全参数。在下面的代码中,32 字节的 key 被分成两个 16 字节的 key 。这同样适用于 iv。第一次加密使用key+0iv+0;第二次加密使用key+16iv+16

cryptopp$ cat test.cxx
#include "cryptlib.h"
#include "filters.h"
#include "files.h"
#include "aes.h"
#include "gcm.h"
#include "hex.h"
#include "hkdf.h"
#include "sha.h"

#include <string>
#include <iostream>

int main(int argc, char* argv[])
{
using namespace CryptoPP;

std::string password = "super secret password";
SecByteBlock key(32), iv(32);

HKDF<SHA256> hkdf;
hkdf.DeriveKey(key, key.size(),
(const byte*)password.data(), password.size(),
NULL, 0, // salt
(const byte*)"key derivation", 14);

hkdf.DeriveKey(iv, iv.size(),
(const byte*)password.data(), password.size(),
NULL, 0, // salt
(const byte*)"iv derivation", 13);


std::string m = "Yoda said, Do or do not. There is no try.";
std::string c1, c2;

GCM<AES>::Encryption encryptor;

encryptor.SetKeyWithIV(key, 16, iv, 16);
StringSource(m, true, new AuthenticatedEncryptionFilter(
encryptor, new StringSink(c1)));

encryptor.SetKeyWithIV(key+16, 16, iv+16, 16);
StringSource(c1, true, new AuthenticatedEncryptionFilter(
encryptor, new StringSink(c2)));

std::cout << "Hex(m):" << std::endl;
StringSource(m, true, new HexEncoder(new FileSink(std::cout)));
std::cout << std::endl;

std::cout << "Hex(Enc(m)):" << std::endl;
StringSource(c1, true, new HexEncoder(new FileSink(std::cout)));
std::cout << std::endl;

std::cout << "Hex(Enc(Enc(m))):" << std::endl;
StringSource(c2, true, new HexEncoder(new FileSink(std::cout)));
std::cout << std::endl;

return 0;
}

程序运行如下:

cryptopp$ ./test.exe
Hex(m):
596F646120736169642C20446F206F7220646F206E6F742E205468657265206973206E6F20747279
2E
Hex(Enc(m)):
D4A9063DE7400E90627DE90D16346DC5A99740C55F6FEE092A99071F55F1BDB25A72B7422126CCC4
09B5B5C0076E39EBF7256D5DC3151A738D
Hex(Enc(Enc(m))):
83A459F2D4A1627624AF162590465AC705C8AC0F4D915E4A4A9D300156C5F9E042CAA47903353F0A
A1FAE408D5747DD223AC4F9AEF3C320EEF7E79E08AB2C6FBEAE7A3A5B4978C45C7

我认为你的方案还有一些额外的问题。例如,如果您对消息“黎明时分进攻!” 进行多次加密,那么每次运行都会得到相同的密文。是信息泄露,缺乏密文不可区分性。

我认为你应该避免你的方案,并使用 Elliptic Curve Integrated Encryption Scheme (ECIES) .它避免了你方案中的大部分潜在问题,并实现了IND-CCA2。 .

ECIES 的缺点是,您必须管理公钥/私钥对。不过,这并不是什么大缺点。您已经在管理密码和 iv,因此从密码更改为私钥并不多。

关于c++ - 重新加密加密数据文件生成解密输出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56859488/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com