如何在文件中读取和写入 AES 密钥?
How to read and write an AES key to and from a file?
我正在尝试将AES密钥写入文件,然后稍后读取。我正在使用加密++库,AES密钥初始化如下。下面,byte
是unsigned char
的类型定义。
byte key[CryptoPP::AES::MAX_KEYLENGTH]
密钥长度为 32 字节。我尝试将其写入文件:
FILE* file = fopen("C:\key", "wb");
fwrite(key, 1, sizeof(key), file);
fclose(file);
并使用以下方法恢复它:
FILE* read_file = fopen("C:\key", "rb");
fseek(read_file, 0, SEEK_END);
long int size = ftell(read_file);
fclose(read_file);
read_file = fopen("C:\key", "rb");
unsigned char * in = (unsigned char *)malloc(size);
byte readed_key = fread(in, sizeof(unsigned char), size, read_file);
fclose(read_file);
if (key == readed_key)
{
cout << "this is the right key !";
}
free(in);
但是,我收到一条错误消息:
不兼容的操作数类型:字节*和字节。
我不明白为什么,因为readed_key
和key
是用byte
而不是byte*
初始化的.
我在Crypto++维基上查看了AES,密钥生成如下。我发现我只是在创建密钥(而不是生成它(:
SecByteBlock key(0x00, AES::MAX_KEYLENGTH);
rnd.GenerateBlock( key, key.size() );
有了那个我不能使用
std::vector<byte> key(32);
rnd.GenerateBlock(key, key.size());
因为rnd.Generateblock
无法转换std::vector< byte > into byte*
这让我发疯了。
如何在文件中读取和写入 AES 密钥?
我将避免使用您的代码,因为它主要是 C 代码。安德鲁指出了它的一些问题,所以重新讨论它是没有意义的。相反,我将向您展示Crypto++和C++做事方式。我也会SecByteBlock
讨论一下。
以下是使用源和接收器将数据读入字节数组的 Crypto++ 方法。您可以在 Crypto++ wiki 中的管道中阅读有关它们的更多信息。
byte key[CryptoPP::AES::MAX_KEYLENGTH];
FileSource fs("C:\key.bin", true, new ArraySink(key, sizeof(key)));
下面是使用源和接收器将数据写入文件的 Crypto++ 方法。
byte key[CryptoPP::AES::MAX_KEYLENGTH];
ArraySource as(key, sizeof(key), true, new FileSink("C:\key.bin"));
以下是使用流将数据读入字节数组C++方法。它取自读取和写入二进制文件
byte key[CryptoPP::AES::MAX_KEYLENGTH];
std::ifstream fs("C:\key.bin", std::ios::binary);
fs.read(key, sizeof(key));
以下是使用流将数据写入文件C++方法。
byte key[CryptoPP::AES::MAX_KEYLENGTH];
std::ofstream fs("C:\key.bin", std::ios::binary);
fs.write(key, sizeof(key));
std::vector<byte> key(32); rnd.GenerateBlock(key, key.size());
因为 rnd。生成块无法将
std::vector< byte >
转换为byte*
.这让我发疯了。
在这里,您需要一个指向第一个元素的非常量指针。取向量中第一个元素的地址。这同样适用于std::string
。
std::vector<byte> key(32);
rnd.GenerateBlock(&key[0], key.size());
由于密钥是敏感的,因此应使用SecByteBlock
。使用完密钥后,它会从内存中将其清零。
一般来说,如果信息是敏感的,那么你想使用SecBlock<T>
。在SecByteBlock
的情况下,T
是一个byte
,并且有一个用于SecByteBlock
的typedef。但是你可以用任何东西来做SecBlock<T>
。
下面是使用源和接收器将数据读入SecByteBlock
的 Crypto++ 方法。
SecByteBlock key(AES::MAX_KEYLENGTH);
FileSource fs("C:\key.bin", true, new ArraySink(key.begin(), key.size()));
SecByteBlock
可以在构造时将元素初始化为已知值。您正在使用以下功能。所有元素都初始化为0x00
。
SecByteBlock key(0x00, AES::MAX_KEYLENGTH);
rnd.GenerateBlock(key, key.size());
由于您将立即用随机数据覆盖元素,因此您应该放弃初始化。只需要求一个未初始化的内存块:
SecByteBlock key(AES::MAX_KEYLENGTH);
rnd.GenerateBlock(key, key.size());
key
是一个byte
数组,即它的类型是byte[32]
(假设CryptoPP::AES::MAX_KEYLENGTH
是一个等于32的整数常数(。 在某些情况下,byte[N]
衰减为byte*
,包括在比较期间使用==
(例如在if (key == readed_key)
行中(。
readed_key
被定义为byte
,这是不一样的。
此外,您不正确地使用了fread (3)
;返回值是读取的项目数,而不是读取的数据。您读取的数据存储在in
数组中。您需要将key
的每个元素与in
的每个元素进行比较,以检查键是否相同。
编辑:感谢@vasek指出应该写比较
if (memcmp(key, in, size) == 0) { /* keys are equal */ }
由于您使用的是C++(Crypto++ 库是一个C++库(,因此您可以使用更高级别的抽象来避免使用malloc
/free
进行手动内存管理,并使代码更易于使用:
现场示例:
#include <cstdint>
#include <fstream>
#include <iostream>
#include <vector>
using byte = char;
int main() {
std::vector<byte> key(32);
// Code would go here to generate the `key`
// ...
{
std::ofstream out("C:\key", std::ios::out | std::ios::binary);
out.write(key.data(), key.size());
} // file is closed automatically here!
std::vector<byte> read_key(32);
{
std::ifstream in("C:\key", std::ios::in | std::ios::binary);
in.read(read_key.data(), read_key.size());
}
if (key == read_key) {
std::cout << "Keys are equal!n";
}
return 0;
}
在这里,std::vector<byte>
处理内存分配(您只需在构造函数中告诉它大小;使用.data()
获取指向内容的指针;完整键的比较是免费的,std::vector
的operator==
(,并且与fread
/fwrite
相比,iostreamsread
/write
的C++更容易遵循。您仍然可以执行查找以确定密钥大小;我会把它留给读者作为练习。
- SSH通过/sbin/SSH无法读取RSA密钥文件(从控制台运行)
- 允许从 std::map 的密钥窃取资源?
- TMap::Emplace() 在应用现有密钥时会覆盖吗?
- 在没有密钥的情况下读取密文的剩余噪声预算
- 如何修复无效的API密钥,IP或操作权限错误?
- 所有可能的链接生成器与64位密钥
- 如何在unordered_map中更改密钥?
- 在Crypto++中向AES解密传递密钥
- 如何使用 AES 和 sha256 哈希作为密钥加密++进行加密
- 在加密++中使用RSA加密对称AES密钥
- 如何在文件中读取和写入 AES 密钥?
- 此示例中指定的此 128 位 AES 密钥的格式是什么
- 如何在 Windows 7 上使用 Crypto API 下一代创建 AES 持久密钥
- 如何使用用户定义的密码初始化AES-256密钥
- 如何通过AES-256-CBC使用密码代替密钥和IV加密文件
- AES和密钥长度误差
- AES、128 和 256 密钥长度无效
- 将密钥和 iv 保存到文件 AES 实现加密++
- 如何在加密++库的AES中找到添加循环密钥和混合列代码
- 正在将明文AES 128密钥导出到缓冲区/文件Windows Crypto API c++