如何在点击模式下搜索并解密部分流

How to seek in CTR mode and decrypt part of the stream?

本文关键字:搜索 解密部 分流 模式      更新时间:2023-10-16

我有一个关于密码部分解码的问题。使用 AES 256 点击率;

编码源:

CTR_Mode< AES >::Encryption e;
e.SetKeyWithIV(key, 32, iv);
string encrypt;
string a = "Example text to encoding";
encrypt.clear();
StringSource s(a, true,
    new StreamTransformationFilter(e,
        new StringSink(encrypt)
    )
);

解码源:

CTR_Mode<AES>::Decryption d;
d.SetKeyWithIV(key, 32, iv);
string x;
StringSource s1(encrypt, true,
    new StreamTransformationFilter(d,
        new StringSink(x)
    )
);

它工作正常。但我不知道如何解密只有一部分。例如,示例encrypt.begin()+10

零件解码:

CTR_Mode<AES>::Decryption d;
d.SetKeyWithIV(key, 32, iv);
d.DiscardBytes(5);  //bit to skip
string todecrypt = encrypt.substr(5,10); // part of encrypted message
string x;
StringSource s1(todecrypt, true,
    new StreamTransformationFilter(d,
        new StringSink(x)
    )
);

如何在CTR模式下搜索并解密部分流?

使用 Crypto++ 管道有点尴尬,因为Source上的DiscardSkip无法按预期工作。在当前实现下,您必须将数据Pump"无"。另请参阅在源上跳过在堆栈溢出上无法按预期工作。

下面是使用 AES/CTR 并在流中搜索的示例。它需要执行"两部分"搜索。首先,它丢弃名为 cipherSource上的字节。其次,它在名为 enc 的加密对象上的密钥流中查找以同步计数器。一旦执行了搜索,密文的其余部分就会通过调用PumpAll()来解密,这将剩余的数据泵送通过管道。

#include "modes.h"
#include "aes.h"
using namespace CryptoPP;
int main(int argc, char* argv[])
{
    string plain = "Now is the time for all good men to come to the aide of their country";
    byte key[AES::DEFAULT_KEYLENGTH] = {0};
    byte nonce[AES::BLOCKSIZE] = {0};
    CTR_Mode<AES>::Encryption enc;
    enc.SetKeyWithIV(key, sizeof(key), nonce, sizeof(nonce));
    string cipher;
    StringSource ss1(plain, true, new StreamTransformationFilter(enc, new StringSink(cipher)));
    for(size_t i=0; i<cipher.size(); i++)
    {   
        CTR_Mode<AES>::Decryption dec;
        dec.SetKeyWithIV(key, sizeof(key), nonce, sizeof(nonce));
        StringSource ss2(cipher, false);
        ss2.Pump(i);
        dec.Seek(i);
        string recover;
        StreamTransformationFilter stf(dec, new StringSink(recover));
        // Attach the decryption filter after seeking
        ss2.Attach(new Redirector(stf));
        ss2.PumpAll();
        cout << i << ": " << recover << endl;
    }
    return 0;
}

结果如下:

$ ./test.exe 
0: Now is the time for all good men to come to the aide of their country
1: ow is the time for all good men to come to the aide of their country
2: w is the time for all good men to come to the aide of their country
3:  is the time for all good men to come to the aide of their country
4: is the time for all good men to come to the aide of their country
5: s the time for all good men to come to the aide of their country
6:  the time for all good men to come to the aide of their country
7: the time for all good men to come to the aide of their country
8: he time for all good men to come to the aide of their country
9: e time for all good men to come to the aide of their country
10:  time for all good men to come to the aide of their country
11: time for all good men to come to the aide of their country
12: ime for all good men to come to the aide of their country
13: me for all good men to come to the aide of their country
14: e for all good men to come to the aide of their country
15:  for all good men to come to the aide of their country
16: for all good men to come to the aide of their country
17: or all good men to come to the aide of their country
18: r all good men to come to the aide of their country
19:  all good men to come to the aide of their country
20: all good men to come to the aide of their country
21: ll good men to come to the aide of their country
22: l good men to come to the aide of their country
23:  good men to come to the aide of their country
24: good men to come to the aide of their country
25: ood men to come to the aide of their country
26: od men to come to the aide of their country
27: d men to come to the aide of their country
28:  men to come to the aide of their country
29: men to come to the aide of their country
30: en to come to the aide of their country
31: n to come to the aide of their country
32:  to come to the aide of their country
33: to come to the aide of their country
34: o come to the aide of their country
35:  come to the aide of their country
36: come to the aide of their country
37: ome to the aide of their country
38: me to the aide of their country
39: e to the aide of their country
40:  to the aide of their country
41: to the aide of their country
42: o the aide of their country
43:  the aide of their country
44: the aide of their country
45: he aide of their country
46: e aide of their country
47:  aide of their country
48: aide of their country
49: ide of their country
50: de of their country
51: e of their country
52:  of their country
53: of their country
54: f their country
55:  their country
56: their country
57: heir country
58: eir country
59: ir country
60: r country
61:  country
62: country
63: ountry
64: untry
65: ntry
66: try
67: ry
68: y

现在您已经了解了常规模式,下面是使用范围[5,10]对数据集进行的修改。

您不必调用stf.MessageEnd()因为一旦 XOR 形成,恢复的文本就已准备就绪。其他模式可能需要调用MessageEnd()。另请参阅Crypto++维基上的Init-Update-Final。

StringSource ss2(cipher, false);
ss2.Pump(5);
dec.Seek(5);
string recover;
StreamTransformationFilter stf(dec, new StringSink(recover));
// Attach the decryption filter after seeking
ss2.Attach(new Redirector(stf));
ss2.Pump(10 - 5 + 1);
cout << "'" << recover << "'" << endl;

它产生:

$ ./test.exe 
's the '

这里还有一点:

StringSource ss2(cipher, false);
ss2.Pump(5);
dec.Seek(5);
string recover;
StreamTransformationFilter stf(dec, new StringSink(recover));
// Attach the decryption filter after seeking
ss2.Attach(new Redirector(stf));
ss2.Pump(10 - 5 + 1);
cout << "'" << recover << "'" << endl;
ss2.Pump(1);
cout << "'" << recover << "'" << endl;
ss2.Pump(1);
cout << "'" << recover << "'" << endl;

它产生:

$ ./test.exe 
's the '
's the t'
's the ti'

早些时候我说过"使用Crypto++管道有点尴尬"。以下是我们想要做的所有事情,但目前还不能:

StringSource ss(cipher, false, new StreamTransformationFilter(dec, new StringSink(x)));
ss.Skip(5); // Discard bytes and synchronize stream
ss.Pump(5); // Process bytes [5,10]
cout << x << endl;

关于 Rob 的评论"您必须解密整个 16 字节块......"> - 如果您使用的是另一种模式,例如 CBC 模式,那么您将不得不处理前面的纯文本或密文;而且你必须在块上操作。CBC模式及其链接属性需要它。

但是,点击率的设计略有不同。它被设计为可搜索的,它允许您在溪流中跳来跳去。在这方面,它很像 OFB 模式。(CTR 模式和 OFB 模式在生成密钥流的方式上有所不同。但两者都是带有纯文本或密文的密钥流(。