在线看毛片网站电影-亚洲国产欧美日韩精品一区二区三区,国产欧美乱夫不卡无乱码,国产精品欧美久久久天天影视,精品一区二区三区视频在线观看,亚洲国产精品人成乱码天天看,日韩久久久一区,91精品国产91免费

<menu id="6qfwx"><li id="6qfwx"></li></menu>
    1. <menu id="6qfwx"><dl id="6qfwx"></dl></menu>

      <label id="6qfwx"><ol id="6qfwx"></ol></label><menu id="6qfwx"></menu><object id="6qfwx"><strike id="6qfwx"><noscript id="6qfwx"></noscript></strike></object>
        1. <center id="6qfwx"><dl id="6qfwx"></dl></center>

            博客專欄

            EEPW首頁 > 博客 > X.509證書的編碼及解析:程序解析以及winhex模板解析

            X.509證書的編碼及解析:程序解析以及winhex模板解析

            發(fā)布人:電子禪石 時間:2021-08-09 來源:工程師 發(fā)布文章

            一、證書的整體結構:證書內容、簽名算法、簽名結果。

            用ASN.1語法描述如下:

            Certificate::=SEQUENCE{
                tbsCertificate      TBSCertificate,
                signatureAlgorithm  AlgorithmIdentifier,
                signatureValue      BIT STRING
            }

            其中,簽名算法為CA對tbsCertificate進行簽名所使用的算法;類型為AlgorithmIdentifier,其ASN.1語法描述如下:

            AlgorithmIdentifier::=SEQUENCE{
                algorithm       OBJECT IDENTIFIER,
                parameters      ANY DEFINED BY algorithm OPTIONAL
            }

            其中,algorithm給出了算法的OID;可選的parameters給出算法的參數(shù)。

            需要注意,algorithm同時說明了雜湊算法和數(shù)字簽名算法,常見的有:(1)MD5wihRSAEncryption, MD5 Hash函數(shù)和RSA簽名算法配合使用,OID為1.2.840.113549.1.1.4。(2)SHA1withRSAEncryption, SHA-1 Hash函數(shù)和RSA簽名算法配合使用,OID為1.2.840.113549.1.1.5。

            簽名結果是CA對tbsCertificate進行簽名的結果,類型為BIT STRING。

            證書內容是需要被CA簽名的信息,ASN.1語法描述如下:

            復制代碼
            TBSCertificate::=SEQUENCE{
                version           [0]   EXPLICIT Version DEFAULT v1,
                serialNumber            CertificateSerialNumber,
                signature               AlgorithmIdentifier,
                issuer                  Name,
                validity                Validity,
                subject                 Name,
                subjectPublicKeyInfo    SubjectPublicKeyInfo,
                issuerUniqueID    [1]   IMPLICIT UniqueIdentifier OPTIONAL,
                subjectUniqueID   [2]   IMPLICIT UniqueIdentifier OPTIONAL,
                extensions        [3]   EXPLICIT Extensions OPTIONAL
            }
            復制代碼

            其中,issuerUniqueID和subjectUniqueID只能在版本2或者3中出現(xiàn);extensions只能在版本3中出現(xiàn)。

             

            下面我們逐一說明TBSCertificate中的每一個字段。

            1>版本號

            版本(version)為整數(shù)格式。到目前為止,證書格式的版本只有v1、v2、v3,分別用整數(shù)0、1、2表示。

            其類型Version的ASN.1描述如下:

            Version::=INTEGER {v1(0),v2(1),v3(2)}

            目前最常用的版本是v3。

            2>序列號

            證書序列號(serialNumber)為整數(shù)格式。

            其類型CertificateSerialNumber的ASN.1描述如下:

            CertificateSerialNumber::=INTEGER

            證書序列號用來在某一個CA范圍內唯一地標識一張證書。由此,“簽發(fā)者”和“證書序列號”配合起來就能唯一地標識一張數(shù)字證書。在很多PKI的通信協(xié)議中使用的就是這種方式。

            RFC 3280標準要求證書序列號必須是正整數(shù),且長度不應該大于20字節(jié)。

            3>簽名算法

            簽名算法(signature)給出了CA簽發(fā)證書時所使用的數(shù)字簽名算法,它的類型與signatureAlgorithm的類型相同,都為AlgorithmIdentifier,它們的值必須一致,否則該證書無效。

            4>簽發(fā)者和主體

            證書的簽發(fā)者(issuer)和證書主體(subject)分別標識了簽發(fā)證書的CA實體和證書持有者實體,兩者類型均為Name。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
            復制代碼

            證書的簽發(fā)者和證書主體用X.509 DN表示,DN是由RDN構成的序列。RDN用“屬性類型=屬性值”的形式表示。常用的屬性類型名稱以及簡寫如下:

            常用RDN屬性類型
            屬性類型名稱含義簡寫
            Common Name通用名稱CN
            Organizational Unit name機構單元名稱OU
            Organization name機構名O
            Locality地理位置L
            State or province name州/省名S
            Country國名C

            5>有效期

            證書有效期(validity)給出證書的有效使用期,包含起、止兩個時間值。時間值可以使用UTCTime或者GeneralizedTime的形式表示。ASN.1描述如下:

            復制代碼
            Validity::=SEQUENCE{
                notBefore       Time,
                notAfter        Time
            }
            Time::=CHOICE{
                utcTime         UTCTime,
                generalTime     GeneralizedTime
            }
            復制代碼

            6>主體公鑰信息

            主體公鑰信息(subjectPublicKeyInfo)給出了證書所綁定的加密算法和公鑰。其ASN.1描述如下:

            SubjectPublicKeyInfo::=SEQUENCE{
                algorithm           AlgorithmIdentifier,
                subjectPublicKey    BIT STRING
            }

            其中,algorithm表示被綁定的、證書主體持有的公鑰密碼算法;subjectPublicKey是具體的公鑰數(shù)據,內容和格式依算法不同而異。對于RSA算法,它包含公鑰參數(shù)e和n。

            7>簽發(fā)者唯一標識符和主體唯一標識符

            簽發(fā)者唯一標識符(issuerUniqueID)和主體唯一標識符(subjectUniqueID)給出了證書簽發(fā)者和證書主體的唯一標識符。UniqueIdentifier類型的ASN.1描述如下:

            UniqueIdentifier::=BIT STRING

             

            二、證書編碼

            針對ASN.1的語法,編碼可以采用“TLV”方式,即依次對數(shù)據的類型(type)、長度(length)、值(value)編碼,這樣就可以完整地表示一個特定類型的數(shù)據?!癟LV”方式的編碼有多種,下面介紹DER這種編碼方式。都是big-endian字節(jié)序。

            1.簡單類型的編碼

            1>BOOLEAN:01

            布爾類型,兩種取值:TRUE(0xFF)、FALSE(0x00)。

            編碼為:

                    T      L      V
            TRUE    01     01     FF
            FALSE   01     01     00

            2>INTEGER:02

            整數(shù)類型。兩種情況:

            第一種,數(shù)據長度不大于0x7F,稱為“短形式”,length占1字節(jié),直接把長度賦給length。舉例:0x123456的DER編碼為:

            T   L   V02  03  12  34 56

            第二種,數(shù)據長度大于0x7F,稱為“長形式”,把數(shù)據長度L表示為字節(jié)碼,計算其長度n,然后把n與0x80進行“位或”運算的結果賦給length的第一個字節(jié)。舉例:0x1234...34(長0100字節(jié)),即n=2,編碼為:

            T   L           V02  82  01  00  12  34 ...  34

            此外,對于整數(shù),還有正負的問題。規(guī)定value的最高位表示符號---0(+) 1(-)  負數(shù)用補碼表示。

            1)對于正數(shù),如最高位為1,則向左擴展00。

            2)對于負數(shù),如其補碼的最高位為0,則向左擴展FF。

            3>BIT STRING:03

            比特串的長度可能不是8的倍數(shù),而DER編碼以字節(jié)為單位。故而,如果需要,則在比特串的最后填若干位“0”,使其長度達到8的倍數(shù);在最前面增加1字節(jié),寫明填充的位數(shù)。特別注意:value部分的第一字節(jié),即表示填充位數(shù)的那個字節(jié),也要計入數(shù)據的總長度。如果不需要填充,則第一字節(jié)也需要用00來表示填充位數(shù)。舉例:1011010010編碼為:

            T   L   V03  03  06  B4 80

            4>OCTET STRING:04

            字節(jié)碼串。舉例:AB CD EF 01 23的編碼為:

            T   L   V04  05  AB  CD  EF  01  23

            5>NULL:05

            編碼是固定的,value部分為空,一共兩字節(jié):

            T   L05  00

            6>OBJECT IDENTIFIER:06

            對象標識符(OID),是一個用“.”隔開的非負整數(shù)組成的序列。下面說下OID的編碼設計:設OID=V1.V2.V3.V4.V5....Vn,則DER編碼的value部分規(guī)則如下:(1)計算40*V1+V2作為第一字節(jié);(2)將Vi(i>=3)表示為128進制,每一個128進制位作為一個字節(jié),再將除最后一個字節(jié)外的所有字節(jié)的最高位置1;(3)依次排列,就得到了value部分。舉例:OID=1.2.840.11359.1.1的編碼如下:

            說明:Vi的最后一個字節(jié)不對最高位置1,系統(tǒng)以此來識別這里是這個字段的最后一字節(jié)。

            7>PrintableString:13

            表示任意長度的ASCII字符串。舉例:“Hello, world”的編碼為:

            T   L   V13  0C  48  65  6C  6C  6F  2C  20  77  6F  72  6C  64

            8>UTCTime:17

            表示時間,可以用GMT格林威治時間(結尾標“Z”)來表示,或者是用本地時間和相對于GMT的偏移量來表示。

            UTCTime的格式如下多種:
            YYMMDDhhmmZ
            YYMMDDhhmm+hh'mm'
            YYMMDDhhmm-hh'mm'
            YYMMDDhhmmssZ
            YYMMDDhhmmss+hh'mm'
            YYMMDDhhmmss-hh'mm'

            其中,

            YY:年的最后2位
            MM:月,01-12
            DD:日,01-31
            hh:小時,00-23
            mm:分鐘,00-59
            ss:秒,00-59
            Z/+/-:Z表示GMT時間,+/-表示本地時間與GMT時間的差距
            hh’:與GMT的差
            mm’:與GMT的差

            舉例:北京時間2008年8月8日晚8時表示成UTCTime為:080808120000Z 或 080808200000-0800 其編碼為:

            T   L   V17  0D  30  38  30  38  30  38  31  32  30  30  30  30  5A
            或
            T   L   V17  11  30  38  30  38  30  38  32  30  30  30  30  30  2D  30  38  30  30

            9>GeneralizedTime:18

            與UTCTime類似,差別只在于用4位數(shù)字表示“年”,以及“秒”可精確到千分位。舉例:北京時間2008年8月8日晚8時1分2.345秒表示成GeneralizedTime為:20080808120102.345Z 或 20080808200102.345-0800 其編碼為:

            T   L   V18  13  32  30  30  38  30  38  30  38  31  32  30  31  30  32  2E  33  34  35  5A
            或
            T   L   V18  17  32  30  30  38  30  38  30  38  32  30  30  31  30  32  2E  33  34  35  2D  30  38  30  30

            2.構造類型數(shù)據的編碼

            1>序列構造類型:30

            SEQUENCE與SEQUENCE OF的type相同,都是30。value部分為序列內所有項目的編碼的依次排列。length為這些項目編碼的總長度。舉例:一天中幾次溫度測量的結果:temperatureInADay SEQUENCE(7) OF INTEGER::={21,15,5,-2,5,10,5}, 其DER編碼為:

            復制代碼
            T   L   V30  15  02  01  15
                    02  01  0F        02  01  05
                    02  01  FE        02  01  05
                    02  01  0A        02  01  05
            復制代碼

            構造類型的定義中,常常包含CHOICE、ANY、OPTIONAL、DEFAULT等關鍵字,其編碼規(guī)則如下:

            (1)CHOICE

            多選一,按照實際選中的類型編碼。舉例:

            Time::=CHOICE{
                utcTime         UTCTime,
                generalizedTime GeneralizedTime
            }

            若實際用到的類型是UTCTime,則數(shù)據用UTCTime的編碼規(guī)則編碼。

            (2)ANY

            類型依賴于另一個域的值,則按照實際類型編碼。舉例:

            AlgorithmIdentifier::=SEQUENCE{
                algorithm       OBJECT IDENTIFIER,
                parameters      ANY DEFINED BY algorithm OPTIONAL
            }

            若algorithm的值表示RSA,則parameters按RSA算法的參數(shù)類型編碼;若algorithm的值表示Diffie-Hellman算法,則parameters按Diffie-Hellman算法的參數(shù)類型編碼。

            (3)OPTIONAL

            所標記的字段在實際中可能存在,也可能不存在。如果有值,則編碼;如果無值,則直接跳過。舉例:

            AlgorithmIdentifier::=SEQUENCE{
                algorithm       OBJECT IDENTIFIER,
                parameters      ANY DEFINED BY algorithm OPTIONAL
            }

            實際中,如果沒有參數(shù)parameters,則相當于

            AlgorithmIdentifier::=SEQUENCE{
                algorithm       OBJECT IDENTIFIER
            }

            (4)DEFAULT

            如果所標記的字段在實際中正好等于缺省值,則可以編碼也可以不編碼,相當于是OPTIONAL;如果不等于缺省值,則應該如實編碼。舉例:

            Certificate::=SEQUENCE{
                version           Version DEFAULT 0
                ......
            }

            若version的值恰好等于0(缺省值),則可以不編碼;否則,必須按其類型編碼。

            2>集合構造類型:31

            SET和SET OF的type都是31,value部分包括集合內所有項目的編碼,length為其總長度。需要注意的是,集合構造類型中的各字段是并列的,邏輯上不分先后,但為了編碼的唯一性,在DER編碼中,編碼的排列是有一定順序的。SET按標簽的順序排列。舉例:

            Name::=SET{
                surname     [0] PrintableString,
                mid-name    [1] PrintableString,
                first-name  [2] PrintableString
            }

            編碼時則按照surname,mid-name,first-name的順序。

            SET OF按字典升序排列,即將各項目的DER結果看做字節(jié)碼從小到大排列。舉例:一天中幾次溫度測量的結果:temperatureInADay SET(7) OF INTEGER::={21,15,5,-2,5,10,5}, 其DER編碼為:

            復制代碼
            T   L   V30  15  02  01  05
                    02  01  05
                    02  01  05
                    02  01  0A        02  01  0F        02  01  15
                    02  01  FE
            復制代碼

            由于排序需要一定的時間和空間代價,故而實際情況中,應避免使用集合構造類型。

            3.標簽

            僅僅以上的編碼規(guī)則是不夠的,會有些出現(xiàn)歧義的情況。比如:有相鄰的字段屬于相同的數(shù)據類型。type相同,則根據編碼的排列順序來區(qū)分他們。一旦其中有字段是可選的,解碼時就不能再僅僅根據排列順序來判斷下一個是哪個字段了,產生歧義。故而,引入了標簽,目的是把相同的type標簽為不同的type,以便區(qū)分。

            標簽分為隱式標簽和顯式標簽兩種。分別如下:

            隱式標簽:

            舉例:

            復制代碼
            Contact::=SEQUENCE{
                name                        PrintableString,
                sex                         BOOLEAN,
                title       [0] IMPLICIT    PrintableString OPTIONAL,
                locality    [1] IMPLICIT    PrintableString OPTIONAL,
                telephone   [2] IMPLICIT    PrintableString OPTIONAL,
                fax         [3] IMPLICIT    PrintableString OPTIONAL
            }
            復制代碼

            DER編碼時,對于加了標簽的項目,按如下規(guī)則編碼:

            對于簡單類型,type=80+tag序號;對于構造類型,type=A0+tag序號。length和value不變。

            例如,上例中如果項目fax被賦值為“86-10-12345678”,則編碼為

            T   L   V83  0E  38  36  2D  31  30  2D  31  32  33  34  35  36  37  38

            顯式標簽:

            舉例:(隱式標簽的例子)

            復制代碼
            Record::=SEQUENCE{
                ......
                time    [1] IMPLICIT    Time    OPTIONAL,
                ......
            }
            Time::=CHOICE{
                utcTime             UTCTime,
                generalizedTime     GeneralizedTime
            }
            復制代碼

            假設time被賦值為UTCTime類型的值080808120000Z,而由于隱式標簽的type編碼覆蓋了表示這一類型的type編碼,導致編碼時無法判斷time究竟是哪種類型,造成混亂。于是這里需要使用顯式標簽。運用顯式標簽,上例描述為:

            復制代碼
            Record::=SEQUENCE{
                ......
                time    [1] EXPLICIT    Time    OPTIONAL,
                ......
            }
            Time::=CHOICE{
                utcTime             UTCTime,
                generalizedTime     GeneralizedTime
            }
            復制代碼

            編碼規(guī)則如下:

            T           L                       V
            A0+Tag序號  原TLV格式編碼的總長度   原TLV格式編碼

            上例中time=080808120000Z的編碼為:

            T   L   V
            A1  0F  17  0D  30  38  30  38  30  38  31  32  30  30  30  30  5A

            事實上,顯式標簽就是在原編碼外再封裝一層。

            三、證書解析 C程序

            X.509證書的編碼及解析:程序解析以及winhex模板解析 - jiu~ - 博客園 (cnblogs.com)

            *博客內容為網友個人發(fā)布,僅代表博主個人觀點,如有侵權請聯(lián)系工作人員刪除。



            關鍵詞: x509

            技術專區(qū)

            關閉