2015-04-15 40 views
2

是否有可能使用加密++庫來解碼任意ASN1數據(它有幾個序列和整數),我已經在一個字節數組中。 ash.h包含所有采用BufferedTransformation作爲輸入的方法,但該類是不同的密碼和哈希的接口,這似乎與我的簡單情況根本沒有關係。我還在cryptlib.h中發現了ASN1Object,但它是另一個接口,我沒有設法找到任何實現類。如何解碼非關鍵ASN1數據?

我是否認爲它對我來說太複雜了,還是實際難以解碼任意ASN1數據?

我實際上是在Swift/objective-c iOS應用程序中使用它,所以如果任何人有任何其他工具的簡單解決方案,讓我知道。

EDIT:添加數據的示例結構

SEQUENCE 
    SEQUENCE 
     INTEGER 
     INTEGER 
    SEQUENCE 
     INTEGER 
     INTEGER 

總是有其包含含有2個整數(ElGamal加密對(克^ R,MH^R))的每一個1到n序列的親本序列。

+1

簡短的答案也許是,它取決於底層的ASN.1類型。你能給我們一個你想要解碼的例子嗎?用文本描述它並使用縮進顯示與ASN.1結構關聯的典型層次結構。它將幫助我們向您展示解決方案的樣子。單擊*編輯*(不要將它添加到註釋中),將示例添加到您的問題中。 – jww

+1

我確實更新了帖子,不確定它是你的意思還是過於簡化 – Kelo

回答

4
SEQUENCE 
    SEQUENCE 
     INTEGER 
     INTEGER 
    SEQUENCE 
     INTEGER 
     INTEGER 

對於這一點,你想是這樣的:

ArraySource as(data, size);  
Integer i1, i2, i3, i4; 

BERSequenceDecoder d1(as); 
    BERSequenceDecoder d2(d1); 
     i1.BERDecode(d2); 
     i2.BERDecode(d2); 
     d2.MessageEnd(); 
    BERSequenceDecoder d3(d2); 
     i3.BERDecode(d3); 
     i4.BERDecode(d3); 
     d3.MessageEnd(); 
    d1.MessageEnd(); 

含有兩個整數(ElGamal加密對(G^R,MH^R))的每個。

一旦你有了參數(見下面),你應該使用參數調用Initialize函數之一。 不要調用那些需要PRNG的人,因爲他們創建參數和密鑰。

請參閱gfpcrypt.h瞭解一些相關的類定義。另見ElGamal - Crypto++ Wiki


下面是產生整數對,它們封裝在ASN.1結構就像你想要的例子。然後它將它們讀回來,並在沒有任何剩餘要消耗的時候停止(即,內部Integer對是可選的)。

你會運行它像./asn1-test.exe./asn1-test.exe 3./asn1-test.exe 6./asn1-test.exe 128。大小僅爲48位,因此您不會浪費時間生成不需要的整數。

static const unsigned int BIT_COUNT = 48; 

int main(int argc, char* argv[]) 
{ 
    unsigned int count = 2; 
    if(argc >= 2 && argv[1] != NULL) 
    { 
     istringstream iss(argv[1]); 
     iss >> count; 

     if(iss.fail()) count = 2; 
    } 

    cout << "Testing " << count << " integer pairs" << endl; 

    // Count to pairs 
    count *= 2; 

    try 
    {    
     AutoSeededRandomPool prng; 

     vector<Integer> vv; 
     vv.resize(count); 

     for(unsigned int i = 0; i < count; i += 2) 
     { 
      vv[i] = Integer(prng, BIT_COUNT); 
      vv[i + 1] = Integer(prng, BIT_COUNT); 
     } 

     // Scratch for holding ASN.1 encoded structures in Crypto++ 
     ByteQueue queue; 

     // Encode them 
     { 
      DERSequenceEncoder outer(queue); 

      for(unsigned int i = 0; i < count; i += 2) 
      { 
       DERSequenceEncoder inner(outer); 

       vv[i].DEREncode(inner); 
       vv[i + 1].DEREncode(inner); 

       inner.MessageEnd(); 
      } 

      outer.MessageEnd(); 
     } 

     // Save it to file (use dumpasn1 to view it) 
     FileSink fs("sequences.der", true); 
     queue.CopyTo(fs); 
     fs.MessageEnd(); 

     // Decode them 
     { 
      BERSequenceDecoder outer(queue); 

      // Ensure we break from the loop based on EndReached() 
      for(; ;) 
      { 
       if(outer.EndReached()) break; 

       BERSequenceDecoder inner(outer); 

       Integer i1, i2; 

       i1.BERDecode(inner); 
       i2.BERDecode(inner); 

       cout << "Pair" << endl; 
       cout << std::hex << " Integer: " << i1 << endl; 
       cout << std::hex << " Integer: " << i2 << endl; 

       inner.MessageEnd(); 
      } 

      outer.MessageEnd(); 
     } 

    } catch (const Exception& ex) { 
     cerr << std::dec << ex.what() << endl; 
     exit (1); 
    } 

    return 0; 
} 

而且這裏是一個運行和卸載的樣子:

$ ./asn1-test.exe 3 
Testing 3 integer pairs 
Pair 
    Integer: 301818b3c631h 
    Integer: 1ff0ebf1ca4bh 
Pair 
    Integer: f97e9d28e9cah 
    Integer: 94813cab125fh 
Pair 
    Integer: 8a146ea68e7ch 
    Integer: 60d48ef2462fh 

$ dumpasn1 sequences.der 
    0 57: SEQUENCE { 
    2 16: SEQUENCE { 
    4 6:  INTEGER 30 18 18 B3 C6 31 
12 6:  INTEGER 1F F0 EB F1 CA 4B 
     :  } 
20 18: SEQUENCE { 
22 7:  INTEGER 00 F9 7E 9D 28 E9 CA 
31 7:  INTEGER 00 94 81 3C AB 12 5F 
     :  } 
40 17: SEQUENCE { 
42 7:  INTEGER 00 8A 14 6E A6 8E 7C 
51 6:  INTEGER 60 D4 8E F2 46 2F 
     :  } 
     : } 

0 warnings, 0 errors. 

這裏有包括節省您的查找它們的麻煩:

#include <iostream> 
using std::ostream; 
using std::cin; 
using std::cout; 
using std::cerr; 
using std::endl; 

#include <string> 
using std::string; 

#include <vector> 
using std::vector; 

#include <sstream> 
using std::istringstream; 

#include <cryptopp/cryptlib.h> 
using CryptoPP::Exception; 

#include <cryptopp/filters.h> 
using CryptoPP::StringSource; 
using CryptoPP::StringSink; 

#include <cryptopp/files.h> 
using CryptoPP::FileSink; 

#include <cryptopp/integer.h> 
using CryptoPP::Integer; 

#include <cryptopp/osrng.h> 
using CryptoPP::AutoSeededRandomPool; 

#include <cryptopp/asn.h> 
#include <cryptopp/oids.h> 
namespace ASN1 = CryptoPP::ASN1; 
using CryptoPP::DERSequenceEncoder; 
using CryptoPP::BERSequenceDecoder; 

#include <cryptopp/queue.h> 
using CryptoPP::ByteQueue; 
+0

非常感謝。在我看來,即使沒有'MessageEnd()'調用也可以工作。這是至關重要的,因爲我自己的數據不包括這些數據。 – Kelo

+1

@Kelo - 在這個例子中,你可能會避免使用'MessageEnd()'調用,但不要養成它的習慣。你最終會發現你缺少數據,因爲數據沒有被刷新。例如,請參見[HexEncoder和Missing Data](http://www.cryptopp.com/wiki/HexEncoder#Missing_Data)。它是一種衆所周知的過濾器問題。 (實際上,它的設計和過濾器正在等待你告訴它清除已緩衝的部分數據)。 – jww