源码下载地址  ——下载服务由我的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; };

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

  1. Webfunny知识分享:webpack sourceMap解析源码

    前端的业务越来越庞大,导致我们需要引入的js等静态资源文件的体积也越来越大,不得不使用压缩js文件的方式来提高加载的效率. 编译工具的诞生,极大地方便了我们处理js文件的这一过程,但压缩后的js文件极 ...

  2. Flink 源码解析 —— 源码编译运行

    更新一篇知识星球里面的源码分析文章,去年写的,周末自己录了个视频,大家看下效果好吗?如果好的话,后面补录发在知识星球里面的其他源码解析文章. 前言 之前自己本地 clone 了 Flink 的源码,编 ...

  3. EventBus源码解析 源码阅读记录

    EventBus源码阅读记录 repo地址: greenrobot/EventBus EventBus的构造 双重加锁的单例. static volatile EventBus defaultInst ...

  4. 分享45个android实例源码,很好很强大

    分享45个android实例源码,很好很强大 http://www.apkbus.com/android-20978-1-1.html 分享45个android实例源码,很好很强大http://www ...

  5. 分享45个android实例源码,很好很强大.收藏吧!!!

    andriod闹钟源代码 http://www.apkbus.com/android-20974-1-1.html android源码分享之指南针程序 http://www.apkbus.com/an ...

  6. Visual Studio 2015开发Qt项目实战经验分享(附项目示例源码)

    Visual Studio 2015开发Qt项目实战经验分享(附项目示例源码)    转 https://blog.csdn.net/lhl1124281072/article/details/800 ...

  7. 转换GMT秒数为日期时间格式-Delphi源码

    转换GMT秒数为日期时间格式-Delphi源码.收藏最近在写PE分析工具的时候,需要转换TimeDateStamp字段值为日期时间格式,这是Delphi的源码. //把GMT时间的秒数转换成日期时间格 ...

  8. 阿里P7分享如何面对枯燥的源码

    一个软件开发人员,工作到了一定的年限(一般是3.4年左右),如果他还没学会阅读源码,那么他就会遇到瓶颈.因为到了这个时候的开发,他应该不仅仅只会做那些 CURD 的业务逻辑,而应该会根据公司的实际情况 ...

  9. 老李推荐:第6章3节《MonkeyRunner源码剖析》Monkey原理分析-事件源-事件源概览-命令翻译类

    老李推荐:第6章3节<MonkeyRunner源码剖析>Monkey原理分析-事件源-事件源概览-命令翻译类   每个来自网络的字串命令都需要进行解析执行,只是有些是在解析的过程中直接执行 ...

  10. 老李推荐:第6章8节《MonkeyRunner源码剖析》Monkey原理分析-事件源-事件源概览-小结

    老李推荐:第6章8节<MonkeyRunner源码剖析>Monkey原理分析-事件源-事件源概览-小结   本章我们重点围绕处理网络过来的命令的MonkeySourceNetwork这个事 ...

随机推荐

  1. QtCreator中pro项目文件格式说明

    名称 说明 QT += core gui 添加本项目中需要的模块,影响后面代码文件include的时候自动弹出下拉选择,如果pro文件没有引入该模块则无法自动语法提示,一般打包发布的时候对应动态库文件 ...

  2. Qt编写安防视频监控系统41-秘钥认证

    一.前言 早些年开源过一个秘钥生成器,做的比较粗糙,离真正的商业应用还差点距离,这次在用户的强烈要求下,对秘钥认证这块做了重新的改版,对原有的类进行了重写,重写后一个类不到300行完成所有的事情,并提 ...

  3. Qt音视频开发44-实时人脸框

    一.前言 在人脸识别到以后,需要在实时视频上将所有人脸框绘制出来,一把来说识别人脸会有多种选择,一个是识别最大人脸,这种场景主要用于刷脸门禁,还有一种是识别所有人脸,这种场景主要用于人脸识别摄像机,就 ...

  4. opencv只在bin目录下编译dll,在lib目录下编译lib,在bin目录下不编译测试程序的各种exe

    penCV是一个开源的计算机视觉库,它提供了多种编程语言的接口.如果你只想编译出DLL和Lib库文件,而不编译EXE(可执行文件),这通常是因为你想要进行某种形式的动态链接或者库的分发,而不关心EXE ...

  5. DotNetBar控件中,删除或移除AdvTree上指定名称的Node

    废话少说,直接上核心代码: string deleteNodeName = "节点1"; //移除advTree上指定名称的Node Node deleteNode = advTr ...

  6. 在Deepin系统上配置微软Windows远程桌面服务

    . 前言 本文主要讲解如何在deepin系统上安装和配置Xrdp远程桌面. Xrdp是微软的远程桌面协议(Remote Desktop Protocol, RDP)的开源版本.在Linux系统上安装X ...

  7. ATM 管理系统的设计与实现(类似毕业设计,附源代码)

    ATM 管理系统的设计与实现 作者前言:本系统通过基本规范化的设计,简单的利用了java基本功能实现了ATM系统,本系统虽然简单,但是逻辑很严密,对于有一定java知识的读者有较大帮助,可以用作参考. ...

  8. CDS标准视图:维护计划 I_MaintenancePlanBasic

    视图名称:维护计划 I_MaintenancePlanBasic 视图类型:基础 视图代码: 点击查看代码 @AbapCatalog.compiler.compareFilter: true @Aba ...

  9. ElasticSearch入门 第二篇

    集群配置----------------------------- ElasticSearch共有两个配置文件,都位于config目录下,分别是elasticsearch.yml和logging.ym ...

  10. LPN问题

    郁昱老师的某次讲座,记录一下! LWE和LPN: 1.LWE是模p的:噪音取自离散高斯分布 2.LPN是模2的:噪音取自伯努利分布 3.LPN很难构造同态加密方案 4.都可以分为判定型和搜索型