如何解码非关键ASN1数据?

Kel*_*elo 3 c++ asn.1 crypto++

是否可以使用 crypto++ 库来解码字节数组中的任意 ASN1 数据(其中有几个序列和整数)。ash.h 包含所有以 BufferedTransformation 作为输入的方法,但该类是不同密码和哈希的接口,这似乎与我的简单情况根本无关。我还在 cryptlib.h 中找到了 ASN1Object,但它是另一个接口,我还没有找到任何实现类。

我是否认为这对我自己来说太复杂了,或者解码任意 ASN1 数据实际上很困难?

我实际上在 Swift/objective-c iOS 应用程序中使用它,所以如果有人使用其他工具有一个简单的解决方案,请告诉我。

编辑:添加数据的示例结构

SEQUENCE
    SEQUENCE
        INTEGER
        INTEGER
    SEQUENCE
        INTEGER
        INTEGER
Run Code Online (Sandbox Code Playgroud)

总有一个父序列包含 1 到 n 个序列,每个序列包含 2 个整数(elgamal 加密对 (g^r, mh^r))。

jww*_*jww 5

SEQUENCE
    SEQUENCE
        INTEGER
        INTEGER
    SEQUENCE
        INTEGER
        INTEGER
Run Code Online (Sandbox Code Playgroud)

为此,您需要类似的东西:

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();
Run Code Online (Sandbox Code Playgroud)

每个包含 2 个整数(elgamal 加密对 (g^r, mh^r))。

一旦获得参数(见下文),您应该使用这些Initialize参数调用函数之一。不要调用那些采用 PRNG 的程序,因为它们会创建参数和密钥。

请参阅gfpcrypt.h了解一些相关的类定义。另请参阅ElGamal - Crypto++ Wiki。


下面是一个生成整数对并将它们打包在您想要的 ASN.1 结构中的示例。然后,它将读回它们,并在没有剩余内容可供消耗时停止(即,内部整数对是可选的)。

你可以像./asn1-test.exeor ./asn1-test.exe 3or ./asn1-test.exe 6or一样运行它./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;
}
Run Code Online (Sandbox Code Playgroud)

运行和转储如下所示:

SEQUENCE
    SEQUENCE
        INTEGER
        INTEGER
    SEQUENCE
        INTEGER
        INTEGER
Run Code Online (Sandbox Code Playgroud)

以下内容可以帮助您省去查找它们的麻烦:

#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;
Run Code Online (Sandbox Code Playgroud)