超值分享:ASN.1格式解析源码(未使用openssl),有助于分析证书、私钥等文件

源码下载地址  ——下载服务由我的HttpServer服务器提供

一款简单的ASN.1格式解析工具,可将ASN.1格式输出,是你分析证书、私钥等文件的必备良器,比如查看公钥大数、私钥大数、加密算法、HASH、MAC算法等。ASN.h(.cpp)包含了ASN.1格式的解析类,ASNFileParse.cpp中提供了常用的pem、der等文件的解析。本源码未使用Openssl库。我在 基于SSL(TLS)的HTTPS网页下载——如何编写健壮的可靠的网页下载 中也是使用该类分析公钥和私钥。

开发环境:Windows+VS2010

 

 

 

 

ASN格式数据分两大类,基本数据类型和结构数据类型,由TAG字段表示。


一、TAG定义
1、Bit8-bit7:用来标示TAG 类型,共有四种,分别是universal(00)、application(01)、context-specific(10)和private(11)。
2、Bit6:表示是否为结构类型(1位结构类型);0则表明编码类型是简单类型。
3、Bit5-bit1:是类型的TAG值。根据bit8-bit7的不同值有不同的含义,具体含义见下表。

当Bit8-bit7为universal(00)时,bit5-bit1的值表示不同的universal的值:
当Bit8-bit7为context-specific(10)时,bit5-bit1的值表示特殊内容:
[0] -- 表示证书的版本
[1] -- issuerUniqueID:表示证书发行者的唯一id
[2] -- subjectUniqueID:表示证书主体的唯一id
[3] -- 表示证书的扩展字段

结构类型掩码:00100000(0x20)

0x60(application)、0xa0(context-specific)、0xc0(private)


二、举例
1、SEQUENCE : 0x30——00110000
1.1、TAG类型位UNIVERSAL(00)
1.2、属于结构类型(1),
1.2、TAG值为16(10000)
所以其类型标示字段值为(00110000),即为0x30。

2、证书扩展字段:0xa0——10100000
2.1、TAG类型为(10)
2.2、属结构类型(1)
2.3、TAG的值为0(00011)
所以其类型标示字段值为(10100000),即为0xa0

三、附:Universal类型(1~31)
[01-0x01] BOOLEAN [有两个值:false或true]
[02-0x02] INTEGER [整型值]
[03-0x03] BIT STRING [0位或多位]
[04-0x04] OCTET STRING [0字节或多字节]
[05-0x05] NULL
[06-0x06] OBJECT IDENTIFIER [相应于一个对象的独特标识数字]
[07-0x07] OBJECT DESCRIPTOR [一个对象的简称]
[08-0x08] EXTERNAL, INSTANCE OF [ASN.1没有定义的数据类型]
[09-0x09] REAL [实数值]
[10-0x0a] ENUMERATED [数值列表,这些数据每个都有独特的标识符,作为ASN.1定义数据类型的一部分]
[11-0x0b]
[12-0x0c] UTF8String
[13-0x0d] RELATIVE-OID
[14-0x0e]
[14-0x0f]
[16-0x10] SEQUENCE, SEQUENCE OF [有序数列,SEQUENCE里面的每个数值都可以是不同类型的,而SEQUENCE OF里是0个或多个类型相同的数据]
[17-0x11] SET, SET OF [无序数列,SET里面的每个数值都可以是不同类型的,而SET OF里是0个或多个类型相同的数据]
[18-0x12] Numeric String [0-9以及空格]
[19-0x13] Printable String [A-Z、a-z、0-9、空格以及符号'()+,-./:=?]
[20-0x14] TeletexString, T61String
[21-0x15] VideotexString
[22-0x16] IA5String
[23-0x17] UTCTime [统一全球时间格式]
[24-0x18] GeneralizedTime
[25-0x19] GraphicString
[26-0x1a] VisibleString, ISO646String
[27-0x1b] GeneralString
[28-0x1c] UniversalString
[29-0x1d] CHARACTER STRING
[30-0x1e] BMPString
[31-0x1f] reserved for future use

 

//////////////////////////////////////////////
// ASN.1的数据基类TLV格式(Tag:Length:Value)
//////////////////////////////////////////////
class IAsnNode
{
public:
    IAsnNode()    {    };
    virtual ~IAsnNode()    {    };

public:
    virtual BOOL Decode(const BYTE* pBuff) = 0;
    virtual BOOL Clone(IAsnNode* pNode) = 0;
    
    // 获取相关数据
    BYTE    GetTag()        {    return m_cTag;    }
    void    SetTag(BYTE cTag)    {    m_cTag = cTag;    }

    // tag属于什么分类
    BYTE    GetCatalog(){
        BYTE c = (m_cTag & 0xc0) >> 6;        // 取最高的两位
        return c;
    }

    // 00、通用类型
    BOOL CatalogIsUniversal(){
        return GetCatalog() == CATALOG_UNIVERSAL;
    }

    // 02、Application
    BOOL CatalogIsApplication(){
        return GetCatalog() == CATALOG_APPLICATION;
    }

    // 03、context-specific
    BOOL CatalogIsContextSpecific(){
        return GetCatalog() == CATALOG_CONTEXT_SPECIFIC;
    }

    // 04、private
    BOOL CatalogIsPrivate(){
        return GetCatalog() == CATALOG_PRIVATE;
    }

    // 是否为结构类型
    BOOL    IsStruct(){
        return IsStruct(m_cTag);
    }

    static    BOOL IsStruct(char cTag){
        return (cTag & 0x20);
    }
protected:
    BYTE        m_cTag;
};

// 非集合类型(用未知类型来代替其它类型,比如字符串,BOOL、Obj)
class CAsnX : public IAsnNode
{    
public:
    CAsnX()    {    
                m_pDataRaw = NULL;
                m_dwDataSize = 0;
                m_dwTagSize = 0;
        };
    virtual ~CAsnX()    {        delete m_pDataRaw;    };

public:
    BOOL    Decode(const BYTE* pBuff);    
    BOOL    Clone(IAsnNode* pNode);

    void    SetData(char cTag, DWORD dwDataLen, BYTE* pData);
    BYTE*    GetData()        {    return (m_pDataRaw+m_dwTagSize);    }
    DWORD    GetDataSize()    {    return m_dwDataSize;    }
    DWORD    GetTagSize()    {    return m_dwTagSize;        }

    BYTE*    GetDataRaw()    {    return m_pDataRaw;    }
    DWORD    GetDataRawSize()    {    return (m_dwDataSize+m_dwTagSize);    }

protected:
    BYTE*    m_pDataRaw;
    DWORD    m_dwDataSize;
    DWORD    m_dwTagSize;
};


// 序列相关的集合
class CAsnSetX : public IAsnNode
{    
public:
    CAsnSetX(BYTE cTag)    {    
            m_cTag = cTag;
    };
    virtual ~CAsnSetX()    {    Clear();    };

    void Clear();
    
public:
    BOOL    Decode(const BYTE* pBuff);
    BOOL    Clone(IAsnNode* pNode);

    DWORD    GetSize(DWORD& dwTagSize, DWORD& dwDataSize);

    int GetDataList(CTypedPtrList<CPtrList, IAsnNode*>& lstData);
    CTypedPtrList<CPtrList, IAsnNode*>& GetList(){    return m_lstSet;        }

    int GetItemCount(){
        return m_lstSet.GetCount();
    }
    // 添加内容
    IAsnNode* AddNode(char cTag, DWORD dwDataLen, BYTE* pData);
    void AddNode(IAsnNode* pNode);

    void GetRawData(BYTE** pData, DWORD& dwDataLen, int iLevel = -1);


//     DWORD    GetDataSize()    {    return m_dwDataSize;    }
//     DWORD    GetTagSize()    {    return m_dwTagSize;        }
//     DWORD    GetDataRawSize()    {    return (m_dwDataSize+m_dwTagSize);    }

protected:
    CTypedPtrList<CPtrList, IAsnNode*> m_lstSet;

//     DWORD    m_dwDataSize;
//     DWORD    m_dwTagSize;
    
};

 

posted @ 2021-07-06 15:22  一只会铲史的猫  阅读(821)  评论(0编辑  收藏  举报