如何解码非关键ASN1数据? [英] How to decode non-key ASN1 data?

查看:256
本文介绍了如何解码非关键ASN1数据?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Is it possible to use crypto++ library to decode arbitrary ASN1 data (which has couple of sequences and integers) which I have in a byte array. ash.h contains methods which all take BufferedTransformation as input, but that class is interface for different ciphers and hashes, which really seems to be not related to my simple case at all. I also found ASN1Object in cryptlib.h but it's another interface and I haven't managed to find any implementing classes.

我以为它太复杂,它实际上难以解码任意ASN1数据?

Have I thought it way too complex for myself or is it actually difficult to decode arbitrary ASN1 data?

我实际上在Swift / objective-c iOS应用程序中使用这个,所以如果任何人有一个简单的解决方案,让我知道。

I am actually using this in Swift/objective-c iOS application, so if anyone has a simple solution with whatever else tool, let me know.

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

Adding an example structure of the data

SEQUENCE
    SEQUENCE
        INTEGER
        INTEGER
    SEQUENCE
        INTEGER
        INTEGER

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

There's always the parent sequence which contains 1 to n sequences which contain 2 integers (elgamal encryption pair (g^r, mh^r)) each.

推荐答案

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();








which contain 2 integers (elgamal encryption pair (g^r, mh^r)) each.

一旦你有参数(见下文),您应该使用参数调用 Initialize 函数之一。

Once you have the parameters (see below), you should call one of the Initialize functions with the parameters. Don't call the ones that take a PRNG because they create parameters and keys.

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

See gfpcrypt.h for some of the relevant class definitions. Also see ElGamal - Crypto++ Wiki.

这里有一个例子,生成整数对并将它们封装在ASN.1结构中,就像你想要的那样。然后读取它们,当没有剩余的消费时停止(即,内部整数对是可选的)。

Here's an example that generates integer pairs and packages them in ASN.1 structures like you desire. It then reads them back in and stops when there's nothing left to consume (i.e., the inner Integer pairs are optional).

你会运行它 ./ asn1-test.exe ./ asn1-test.exe 3 ./ asn1-test。 exe 6 ./ asn1-test.exe 128 。大小只有48位,所以你不会浪费时间生成你不需要的整数。

You would run it like ./asn1-test.exe or ./asn1-test.exe 3 or ./asn1-test.exe 6 or ./asn1-test.exe 128. The size is only 48-bits so you don't waste time generating integers you don't need.

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

这里是一个运行和转储看起来像:

And here's what a run and dump looks like:

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

以下是包含节省您查找问题的方法:

Here are the includes to save you the trouble of looking them up:

#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;

这篇关于如何解码非关键ASN1数据?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆