【问题标题】:Convert string to byte in crypto++在crypto++中将字符串转换为字节
【发布时间】:2018-03-25 17:18:20
【问题描述】:

我正在使用带有 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;
}

【问题讨论】:

标签: c++ visual-studio aes crypto++


【解决方案1】:

我有一个在加密期间记录在文件中的密钥。我从文件中提取密钥到字符串并尝试用于解密。

听起来您的文件结构类似于以下:

[...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;
}

您可以致电AttachDetach 来附加新过滤器。两者都附上了一个新的过滤器。不同之处在于,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 &gt;&gt; s1; 应该在TextFile1.eof() 检查之间。在您尝试执行读取之前,您不会到达eof())。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-10-10
    • 1970-01-01
    • 1970-01-01
    • 2022-01-18
    相关资源
    最近更新 更多