天天看點

使用Python Openssl庫解析X509證書資訊X.509 證書結構描述源代碼編譯運作輸出結果

X.509 證書結構描述

常見的X.509證書格式包括:

字尾 作用
cer/crt 用于存放證書,它是2進制形式存放的,不含私鑰
pem 以Ascii來表示,可以用于存放證書或私鑰。
pfx/p12 用于存放個人證書/私鑰,他通常包含保護密碼,2進制方式。
p10 證書請求
p7r CA對證書請求的回複,隻用于導入
p7b 以樹狀展示證書鍊(certificate chain),同時也支援單個證書,不含私鑰。

對于常見的https證書 一般是用crt或者pem來儲存, http證書可電器網頁前的鎖按鈕得到, 并且進行導出

使用Python Openssl庫解析X509證書資訊X.509 證書結構描述源代碼編譯運作輸出結果

證書資料結構

此證書結構來着白皮書

https://tools.ietf.org/html/rfc2459#section-4.1

Certificate ::= SEQUENCE {

        tbsCertificate       TBSCertificate, -- 證書主體

        signatureAlgorithm   AlgorithmIdentifier, -- 證書簽名算法辨別

        signatureValue       BIT STRING --證書簽名值,是使用signatureAlgorithm部分指定的簽名算法對tbsCertificate證書主題部分簽名後的值.

         }

   TBSCertificate ::= SEQUENCE {

        version         [0] EXPLICIT Version DEFAULT v1, -- 證書版本号

        serialNumber         CertificateSerialNumber, -- 證書序列号,對同一CA所頒發的證書,序列号唯一辨別證書

        signature            AlgorithmIdentifier, --證書簽名算法辨別

        issuer               Name,                --證書發行者名稱

        validity             Validity,            --證書有效期

        subject              Name,                --證書主體名稱

        subjectPublicKeyInfo SubjectPublicKeyInfo,--證書公鑰

        issuerUniqueID [1] IMPLICIT UniqueIdentifier OPTIONAL,

                             -- 證書發行者ID(可選),隻在證書版本2、3中才有

        subjectUniqueID [2] IMPLICIT UniqueIdentifier OPTIONAL,

                             -- 證書主體ID(可選),隻在證書版本2、3中才有

        extensions      [3] EXPLICIT Extensions OPTIONAL

                             -- 證書擴充段(可選),隻在證書版本3中才有

        }

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

   CertificateSerialNumber ::= INTEGER



   AlgorithmIdentifier ::= SEQUENCE {

        algorithm               OBJECT IDENTIFIER,

        parameters              ANY DEFINED BY algorithm OPTIONAL }

   parameters:

   Dss-Parms ::= SEQUENCE { -- parameters ,DSA(DSS)算法時的parameters,

RSA算法沒有此參數

        p             INTEGER,

        q             INTEGER,

        g             INTEGER }



signatureValue:

Dss-Sig-Value ::= SEQUENCE { -- sha1DSA簽名算法時,簽名值

                   r       INTEGER,

                      s       INTEGER }



   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



   Validity ::= SEQUENCE {

        notBefore      Time,  -- 證書有效期起始時間

        notAfter       Time  -- 證書有效期終止時間

        }

   Time ::= CHOICE {

        utcTime        UTCTime,

        generalTime    GeneralizedTime }

   UniqueIdentifier ::= BIT STRING

   SubjectPublicKeyInfo ::= SEQUENCE {

        algorithm            AlgorithmIdentifier, -- 公鑰算法

        subjectPublicKey     BIT STRING            -- 公鑰值

        }

subjectPublicKey:

RSAPublicKey ::= SEQUENCE { -- RSA算法時的公鑰值

         modulus            INTEGER, -- n

         publicExponent     INTEGER -- e -- }



   Extensions ::= SEQUENCE SIZE (1..MAX) OF Extension

   Extension ::= SEQUENCE {

        extnID      OBJECT IDENTIFIER,

        critical    BOOLEAN DEFAULT FALSE,

        extnValue   OCTET STRING }

           

參考部落格:

https://blog.csdn.net/xy010902100449/article/details/52145009

源代碼

這裡利用的是python3 的 Openssl 庫進行解析, 此庫的說明文檔如下,

https://pyopenssl.org/en/0.15.1/api/crypto.html#x509name-objects

通過閱讀說明文檔, 可以輕松讀驗證書相關資訊

代碼如下

import OpenSSL
import time
from dateutil import parser

cert = OpenSSL.crypto.load_certificate(OpenSSL.crypto.FILETYPE_PEM, open("test.cer").read())
certIssue = cert.get_issuer()

print ("證書版本:            ",cert.get_version() + 1)

print ("證書序列号:          ",hex(cert.get_serial_number()))

print ("證書中使用的簽名算法: ",cert.get_signature_algorithm().decode("UTF-8"))

print ("頒發者:              ",certIssue.commonName)

datetime_struct = parser.parse(cert.get_notBefore().decode("UTF-8"))

print ("有效期從:             ",datetime_struct.strftime('%Y-%m-%d %H:%M:%S'))

datetime_struct = parser.parse(cert.get_notAfter().decode("UTF-8"))

print ("到:                   ",datetime_struct.strftime('%Y-%m-%d %H:%M:%S'))

print ("證書是否已經過期:      ",cert.has_expired())

print("公鑰長度" ,cert.get_pubkey().bits())

print("公鑰:\n" ,OpenSSL.crypto.dump_publickey(OpenSSL.crypto.FILETYPE_PEM, cert.get_pubkey()).decode("utf-8"))

print("主體資訊:")

print("CN : 通用名稱  OU : 機構單元名稱")
print("O  : 機構名    L  : 地理位置")
print("S  : 州/省名   C  : 國名")

for item in certIssue.get_components():
    print(item[0].decode("utf-8"), "  ——  ",item[1].decode("utf-8"))

print(cert.get_extension_count())

           

編譯運作輸出結果

使用Python Openssl庫解析X509證書資訊X.509 證書結構描述源代碼編譯運作輸出結果

windows 自帶的解析結果對比

使用Python Openssl庫解析X509證書資訊X.509 證書結構描述源代碼編譯運作輸出結果

是完全相同的. 讀取成功

繼續閱讀