2016-11-01 6 views
2

私はcryptoppの部分的な解読に疑問があります。 AES 256 CTRを使用する。CTRモードでシークしてストリームの一部を復号するにはどうすればよいですか?

エンコードソース:

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モードで求め、ストリームの一部を復号化する方法

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) 
    ) 
); 
+2

+10ここで意味をなさないでしょう。ブロックモードが何であっても、16バイトブロック全体を解読する必要があります。 CTRで可能ですが、やや複雑ですが、Crypto ++に直接サポートがあるかどうか覚えていないので、これを達成するために重要なコードが必要ですか?)小さなオフセットの場合、利点はありません。最初のNバイトを捨ててください。 –

+0

@jwwこれはまだ16バイトを解読する必要があります。 AESは常に16バイトを暗号化/復号化します。したがって、バイト10を復号化する場合は、バイト0-9を復号化する必要があります。データではなくキーが変更されても、それは変更されません。あなた自身がこれを覚えています。「求めるモジューロ16」したがって、バイト10を復号化することは、通常の復号化と単純に出力のバイト0-9をスローすることと同じです。あなたは(完全に同意する)と言って、CTRが許可するので、適切な量の暗号テキストを取り除くことは可能です。ライブラリがそれのために設計されていない限り、* code *では複雑です。私はCrypto ++はそうではないと思います。 –

+0

あなたの言ってる事がわかります。 –

答えて

1

Crypto++ Pipelineを使用すると、少し厄介です。Discard or Skip on a Source does not work as expectedです。現在の実装では、Pumpのデータを"nothing"に入力する必要があります。スタックオーバーフローのSkip'ing on a Source does not work as expectedも参照してください。

以下は、AES/CTRを使用してストリームでシークする例です。それは "2つの部分"シークを実行する必要があります。まず、Sourcecipherという名前のバイトを破棄します。次に、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; 
} 

結果である:今、あなたは一般的なパターンを見てきたことを、ここに範囲[5,10]を使用して、データセットの変更がある

$ ./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 

あなたはではありませんstf.MessageEnd()に電話する必要があります。なぜなら、復元されたテキストはXORが実行されるとすぐに準備ができているからです。他のモードではMessageEnd()への呼び出しが必要な場合があります。 Crypto ++ wikiのInit-Update-Finalも参照してください。

$ ./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; 

それは生産

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++ Pipelineを使用するのは少し厄介です"。ここでは、やりたいのですが、我々は現時点ではできません。

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; 

はロブさんのコメント「あなたは全体の16バイトのブロックを復号化する必要があります...」について - あなたが作業していた場合CBCモードのような別のモードでは、先行するプレーンテキストまたは暗号テキストを処理する必要があります。ブロックを操作する必要があります。 CBCモードと連鎖プロパティはそれを要求します。

しかし、CTRは少し異なって設計されています。それはシークできるように設計されており、ストリーム内を飛び回ることができます。この点では、OFBモードによく似ています。 (CTRモードとOFBモードは、キーストリームを生成する方法が異なりますが、どちらもキーストリームとプレーンテキストまたは暗号テキストをXORします)。

関連する問題