1 X.509 证书结构描述
1.1 整体结构
证书内容、签名算法、签名结果。
tbsCertificate | TBSCertificate |
---|---|
signatureAlgorithm | AlgorithmIdentifier |
signatureValue | BIT STRING |
1.2 证书内容
成员 | ASN.1语法(类型) |
---|---|
版本号Version | Version |
序列号Serial Number | CertificateSerialNumber |
签名算法signature | AlgorithmIdentifier |
颁布者issuer | Name |
有效期validity | Validity |
主体subject | Name |
主体公钥信息subjectPublicKeyInfo | SubjectPublicKeyInfo |
颁发者唯一标识符issuerUniqueID | IMPLICIT UniqueIdentifier OPTIONAL |
主体唯一标识符subjectUniqueID | IMPLICIT UniqueIdentifier OPTIONAL |
拓展项extensions | EXPLICIT Extensions OPTIONAL |
其中:
1.2.1 版本号
版本(version)为整数格式。到目前为止,证书格式的版本只有v1、v2、v3,分别用整数0、1、2表示。
ASN.1描述如下:
Version::=INTEGER {v1(0),v2(1),v3(2)}
1.2.2 序列号
整数格式。
ASN.1描述如下:
CertificateSerialNumber::=INTEGER
证书序列号用来在某一个CA内唯一地标识一张证书。由此,“颁布者”和“证书序列号”配合起来就能唯一地标识一张数字证书。
1.2.3 签名算法
CA签发证书时所使用的数字签名算法,与signatureAlgorithm的值必须一致。
1.2.4 颁布者和主体
签发证书的CA实体和证书持有者实体。ASN.1描述如下:
Name::=CHOICE{
RDNSequence
}
RDNSequence::=SEQUENCE OF RelativeDistinguishedName
RelativeDistinguishedName::=SET OF AttributeTypeAndValue
AttributeTypeAndValue::=SEQUENCE{
type AttributeType,
value AttributeValue
}
AttributeType::=OBJECT IDENTIFIER
AttributeValue::=ANY DEFINED BY AttributeType
RDN(Relative Distinguished Name)用“属性类型=属性值”的形式表示。常用的属性类型名称以及简写如下:
属性类型名称 | 含义 | 简写 |
---|---|---|
Common Name | 通用名称 | CN |
Organizational Unit name | 机构单元名称 | OU |
Organization name | 机构名 | O |
Locality | 地理位置 | L |
State or province name | 州/省名 | S |
Country | 国名 | C |
1.2.5 有效期
证书的有效使用期,包含起、止两个时间值。
ASN.1描述:
Validity::=SEQUENCE{
notBefore Time,
notAfter Time
}
Time::=CHOICE{
utcTime UTCTime,
generalTime GeneralizedTime
}
2049年以前的,采用UTCTime。
1.2.6 主体公钥信息
证书所绑定的加密算法和公钥。
SubjectPublicKeyInfo::=SEQUENCE{
algorithm AlgorithmIdentifier,
subjectPublicKey BIT STRING
}
1.2.7 颁布者唯一标识符和主体唯一标识符
issuerUniqueID和subjectUniqueID只能在版本2或者3中出现;extensions只能在版本3中出现。
ASN.1描述:
UniqueIdentifier::=BIT STRING
1.2.8 拓展项
只能在版本3中出现。
1.3 编码
X.509证书的结构用ASN1(Abstract Syntax Notation One)描述数据结构,并使用ASN1语法进行编码。
ASN1采用一个个的数据块来描述整个数据结构,每个数据块都有四个部分组成。
1.3.1 数据块数据类型标识(一个字节)
数据类型包括简单类型和结构类型。
1.3.1.1 bit8-bit7
用来标示 TAG (bit5-bit1)类型,共有四种,分别是universal(00)、application(01)、context-specific(10)和private(11)。
1.3.1.2 bit6
表示是否为结构类型。1为结构类型,0为简单类型。
1.3.1.3 bit5-bit1
类型的TAG值。根据bit8-bit7的不同值有不同的含义。
整个字节表示数据类型。常见的有:
BOOLEAN:01
INTEGER:02
BIT STRING:03
OCTET STRING:04
NULL:05
OBJECT IDENTIFIER:06
PrintableString:13
UTCTime:17
GeneralizedTime:18
序列构造类型SEQUENCE与SEQUENCE OF:0x30
集合构造类型SET和SET OF:0x31
1.3.2 数据块长度(1-128个字节)
长度字段,有两种编码格式。
若长度值小于等于127,则用一个字节表示,bit8 = 0,bit7-bit1存放长度值;
若长度值大于127,则用多个字节表示,可以有2到127个字节。第一个字节的第8位为1,其它低7位给出后面该域使用的字节数量,从该域第二个字节开始给出数据的长度,高位优先。
还有一种特殊情况,这个字节为0x80,表示数据块长度不定,由数据块结束标识结束数据块。
1.3.3 数据块的值
存放数据块的值,具体编码随数据块类型不同而不同。
1.3.4 数据块结束标识(可选)
结束标示字段,两个字节(0x0000),只有在长度值为不定时(数据块长度字段为0x80)才会出现。
2 源代码
# include <iostream>
# include <string.h>
# include <stdlib.h>
# include <map>
using namespace std;
typedef unsigned char byte;
struct Algorithm{
string algorithm;
string parameters;
};
struct SubjectPublicKeyInfo{
Algorithm algorithm;
string SubjectPublicKey;
};
struct TBSCertificate{
char version;
string serialNumber;
Algorithm signature;
string issuer[8];
string validity[2];
string subject[8];
SubjectPublicKeyInfo subjectPublicKeyInfo;
string issuerUniqueID;
string subjectUniqueID;
};
struct Certificate{
TBSCertificate tbsCertificate;
Algorithm signatureAlgorithm;
string Signature;
};
Certificate certificate;
char value[1000];
map<string, string> sa; // OID对应的算法
map<string, string> issuerInfo; // OID对应的属性名
int end = 1;
FILE *fp;
int count = 0;
void OID();
void show(int);
int block();
int main(){
// 打开文件
string file = "../测试证书/ca.cer";
fp = fopen(file.c_str(), "rb"