当前位置: 首页 > 知识库问答 >
问题:

用密文加密++CBC AES加密存储IV

郗浩言
2023-03-14

我试图在CBC模式下使用AES和Crypto++库加密(和解密)一个文件

以下是我已经做的:

using namespace CryptoPP;
AutoSeededRandomPool rnd;

//generating the key and iv
SecByteBlock key(AES::MAX_KEYLENGTH);
rnd.GenerateBlock(key, key.size());
byte iv[AES::BLOCKSIZE];
rnd.GenerateBlock(iv, AES::BLOCKSIZE);

为了加密文件,我以二进制模式打开它,并将内容转储为字符串:

std::ifstream fin(file_path, std::ios::binary);
if (!fin)
{
    std::cout << "error";
}
std::ostringstream ostrm;
ostrm << fin.rdbuf();
std::string plaintext(ostrm.str());
fin.close();
std::string ciphertext;

AES::Encryption aesEncryption(key, CryptoPP::AES::MAX_KEYLENGTH);
CBC_Mode_ExternalCipher::Encryption cbcEncryption(aesEncryption, iv);

StreamTransformationFilter stfEncryptor(cbcEncryption, new CryptoPP::StringSink(ciphertext));
stfEncryptor.Put(reinterpret_cast<const unsigned char*>(plaintext.c_str()), plaintext.length() + 1);
stfEncryptor.MessageEnd();
std::ofstream fdout(file_path2, std::ios::binary);
if (!fdout)
{
    std::cout << "error";
}
fdout << iv;
fdout << ciphertext;
fdout.close();

当我将尝试解密此文件时,我如何分别提取iv和密文?IV是16字节长,但在这里我完全迷失了,我不知道如何做。

共有1个答案

家志学
2023-03-14

用密文加密++CBC AES加密存储IV

你使用的一些代码对我来说有点不寻常。我将挑出一些东西,并向您展示一些crypto++的方法。

在开始之前,先看一下Crypto++维基上的管道和泵送数据。请记住,数据是从源流向接收器的。在数据之间,会遇到对数据进行转换的过滤器。

std::ifstream fin(file_path, std::ios::binary);
if (!fin)
{
    std::cout << "error";
}
std::ostringstream ostrm;
ostrm << fin.rdbuf();
std::string plaintext(ostrm.str());
fin.close();
std::ifstream fin(file_path, std::ios::binary);
FileSource source(fin, true /*pump all*/, NULLPTR);
...
AES::Encryption aesEncryption(key, CryptoPP::AES::MAX_KEYLENGTH);
CBC_Mode_ExternalCipher::Encryption cbcEncryption(aesEncryption, iv);
 CBC_Mode<AES>::Encryption encryptor;

此外,您通常希望避免仅保密模式。通常,您希望使用经过身份验证的加密操作模式。它提供了保密性和真实性。

Crypto++提供了CCM、EAX和GCM认证的加密操作模式。OCB和EAX是非常好的选择。EAX模式在Crypto++Wiki上以EAX模式进行了记录。目前OCB不可用。我们正准备进入OCB模式。

现在,我想把加密的字符串写到一个文件中,并把IV和它一起存储,因为IV不需要保密,最好是在密文的开头或结尾

使用如下所示。我没有编译它,所以你需要修复错别字。

AutoSeededRandomPool prng;
SecByteBlock key(AES::MAXIMUM_KEYLENGTH), iv(AES::BLOCKSIZE);

RandomNumberSource rs1(prng, AES::MAXIMUM_KEYLENGTH, new ArraySink(key, key.size()));
RandomNumberSource rs2(prng, AES::BLOCKSIZE, new ArraySink(iv, iv.size()));

HexEncoder encoder(new FileSink(std::cout));

std::cout << "Key: ";
encoder.Put(key, key.size());
encoder.MessageEnd();
std::cout << std::endl;

std::cout << "IV: ";
encoder.Put(iv, iv.size());
encoder.MessageEnd();
std::cout << std::endl;

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

// Plaintext message
std::string message;

// Output file
FileSink file("message.enc");

// Source wrappers
ArraySource as(iv, iv.size(), true,
    new Redirector(file));

// Source wrapper
StringSource ss(message, true,
    new StreamTransformationFilter(encryptor,
       new Redirector(file)));

当我将尝试解密此文件时,我如何分别提取iv和密文?

使用如下所示。

// Key is from previous example. It cannot change
SecByteBlock key(AES::MAXIMUM_KEYLENGTH), iv(AES::BLOCKSIZE);    
FileSource fs("message.enc", false /* DO NOT Pump All */);

// Attach new filter
ArraySink as(iv, iv.size());
fs.Attach(new Redirector(as));
fs.Pump(AES::BLOCKSIZE);  // Pump first 16 bytes

EAX<AES>::Decryption decryptor;
decryptor.SetKeyWithIV(key, key.size(), iv, iv.size());

// Detach previously attached filter, attach new filter
ByteQueue queue;
fs.Detach(new StreamTransformationFilter(decryptor, new Redirector(queue)));
fs.PumpAll();  // Pump remainder of bytes
SecByteBlock block(queue.MaxRetrievable());
ArraySink sink(block, block.size());
queue.TransferTo(sink);
std::string recovered;
StringSink sink(recovered);
queue.TransferTo(sink);
HexEncoder encoder(new FileSink(std::cout));

std::cout << "IV: ";
encoder.Put(iv, iv.size());
encoder.MessageEnd();
std::cout << std::endl;
 类似资料:
  • 我有一个premium storage account,在创建这个帐户后我就启用了加密,我找到了这个链接https://docs.microsoft.com/en-us/azure/storage/storage-service-encryption来检查blob是否加密。 现在,如果我使用Azure key vault加密OS盘和数据盘,它也用于保护静止数据,但加密存储帐户也会做同样的事情。有谁

  • 当我开始我的申请时,它给了我下面提到的异常。我正在使用加密存储类,但不知道为什么会有这个异常,即使我现在没有访问任何存储类。请引导。 [EDT]0:0:0,32-Exception:java.io.eofException-null java.io.eofException at java.io.datainputstream.readfilly(datainputstream.java:197)

  • 我在工作中被要求保护保存在Mysql数据库中的敏感数据。这个数据库包含几个表,其中一个表中的关键数据只能使用Django中的API来访问。对于这个API,只有一定数量的人可以访问它,因此他们将是唯一能够访问这个表中的数据的人。 因此,目前的问题是每个人都可以访问数据库和该表,因此我们决定使用AES在AES_ENCRYPT()和AES_DECRYPT()函数的帮助下加密该表中的所有数据(根据http

  • 我已经创建了Azure VM,并在其中安装了我的Java应用程序,然后连接到WASB存储。 我添加了以下jars和core-site.xml来从Java应用程序访问WASB存储。 Azure-存储 Hadoop-Azure core-site.xml 如何使用加密密钥访问WASB存储。上面的配置有样例吗? 注意:-我将Azure VM直接连接到WASB存储,而不使用HDInsight集群。

  • MySQL Server Enterprise edition与Hashicorp集成,在静止状态下加密数据。加密密钥存储在HashiCorp存储库中,如MySQL文档中所述。 基于HashiCorp文档[1][2],我们可以使用Azure密钥库来存储秘密。 是否可以集成mysql-hashicorp-Azure密钥库 MySQL Enterprise Edition使用hashicorp加密 加

  • 我正在尝试使用KMS和AWS加密SDK加密数据。查看AWS文档中提供的示例,似乎没有地方可以显式设置数据键。 使用由KMS生成的数据密钥使用AWS加密SDK加密数据的推荐方法是什么?