我正在使用带有Crypto ++的AES密码。我在加密期间有一个记录在文件中的密钥。我将密钥从文件提取到字符串并尝试用于解密。
有什么办法可以将包含密钥string s1
的字符串转换为CryptoPP::byte
吗?有代码片段。
encoded.clear();
StringSource(key, sizeof(key), true,
new HexEncoder(
new StringSink(encoded)
));
ofstream fout1("key.txt");
fout1 << encoded;
fout1.close();
string s1;
ifstream TextFile1("key.txt");
while (!TextFile1.eof())
{
if (TextFile1.eof())
break;
TextFile1 >> s1;
}
答案 0 :(得分:0)
我在加密期间有一个记录在文件中的密钥。我将密钥从文件提取到字符串并尝试用于解密。
听起来你有一个类似于下面的文件结构:
[...key...][...iv...][...encrypted data...]
存储这样的密钥有点不寻常,但这是怎么回事......下面我假设您在CTR模式下使用AES-128。这意味着[...key...]
是16个字节,[...iv...]
是16个字节。其余部分是加密数据。
我用:
生成示例文件$ head -c 128 < /dev/urandom > message.enc
$ hexdump -C message.enc
00000000 17 44 79 6b e6 96 ff d0 9e 3e 8c c4 fe 57 56 a2 |.Dyk.....>...WV.|
00000010 bb 59 9c a6 fb ab 73 de a7 a9 4a 22 14 6e c4 af |.Y....s...J".n..|
00000020 31 13 04 4d f2 79 f8 7c 7a 0b 16 2c bd be 6e 4c |1..M.y.|z..,..nL|
00000030 b6 61 0a 6c 33 d3 f0 73 25 44 ec f5 cd f5 cd da |.a.l3..s%D......|
00000040 3d 13 72 98 65 19 e1 c5 f8 49 1e 07 c7 dc ac b7 |=.r.e....I......|
00000050 ce 03 d1 90 94 08 aa 9d a0 8b b0 cd ff 9c b9 67 |...............g|
00000060 8a 2c 6f d9 7e fa d2 07 0f a0 48 99 57 77 2b d1 |.,o.~.....H.Ww+.|
00000070 c7 28 2a bc 80 22 21 fb 4a ba cb b2 0e b6 2c ff |.(*.."!.J.....,.|
关键是17 44 ... 56 a2
。 iv是bb 59 ... c4 af
。加密数据从31 13 04 4d...
开始。
程序:
$ cat test.cxx
#include "filters.h"
#include "files.h"
#include "modes.h"
#include "aes.h"
#include "hex.h"
#include <iostream>
int main()
{
using namespace CryptoPP;
// Key and iv are stored at the head of the file
SecByteBlock key(16), iv(16);
FileSource fs("message.enc", false /* DO NOT Pump All */);
// Attach new filter
ArraySink ak(key, key.size());
fs.Detach(new Redirector(ak));
fs.Pump(16); // Pump first 16 bytes
// Attach new filter
ArraySink av(iv, iv.size());
fs.Detach(new Redirector(av));
fs.Pump(16); // Pump next 16 bytes
CTR_Mode<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
std::cout << "Key: ";
StringSource(key, key.size(), true, new HexEncoder(new FileSink(std::cout)));
std::cout << std::endl;
std::cout << "IV: ";
StringSource(iv, iv.size(), true, new HexEncoder(new FileSink(std::cout)));
std::cout << std::endl;
std::cout << "Message: ";
HexEncoder hex(new FileSink(std::cout));
queue.TransferTo(hex);
std::cout << std::endl;
return 0;
}
您可以拨打Attach
或Detach
来附加新过滤器。两者都附加一个新过滤器。区别在于,Attach
返回旧过滤器,您必须释放它。 Detach
会为您删除旧过滤器。
最后:
$ g++ -Wall -I . test.cxx ./libcryptopp.a -o test.exe
$ ./test.exe
Key: 1744796BE696FFD09E3E8CC4FE5756A2
IV: BB599CA6FBAB73DEA7A94A22146EC4AF
Message: 84F6DC079CA04BDFACB645CB11CC2F828573F1841B1B9267CB296B6A977BE19D68B05FA
AF41AB73498F45629EE050B132174A2798C12C29A7033ADD1999BECD00B101F2616112D7E6968EA0
A1BE159CD0EE43549BA6534C8D4AB8F5E7D9E3E44
与Crypto ++无关,您通常希望避免这种情况:
while (!TextFile1.eof())
{
if (TextFile1.eof())
break;
TextFile1 >> s1;
}
我认为通常最好关注Why is iostream::eof inside a loop condition considered wrong?(我甚至认为TextFile1 >> s1;
应该在TextFile1.eof()
项检查之间。在尝试之前,您无法到达eof()
执行阅读。