• 使用Python Openssl库解析X509证书信息


    X.509 证书结构描述

    常见的X.509证书格式包括:

    后缀 作用
    cer/crt 用于存放证书,它是2进制形式存放的,不含私钥
    pem 以Ascii来表示,可以用于存放证书或私钥。
    pfx/p12 用于存放个人证书/私钥,他通常包含保护密码,2进制方式。
    p10 证书请求
    p7r CA对证书请求的回复,只用于导入
    p7b 以树状展示证书链(certificate chain),同时也支持单个证书,不含私钥。

    对于常见的https证书 一般是用crt或者pem来保存, http证书可电器网页前的锁按钮得到, 并且进行导出

    在这里插入图片描述

    证书数据结构

    此证书结构来着白皮书
    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(可选),只在证书版本23中才有
    
            subjectUniqueID [2] IMPLICIT UniqueIdentifier OPTIONAL,
    
                                 -- 证书主体ID(可选),只在证书版本23中才有
    
            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("公钥:
    " ,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())
    
    

    编译运行输出结果

    在这里插入图片描述

    windows 自带的解析结果对比

    在这里插入图片描述

    是完全相同的. 读取成功

  • 相关阅读:
    Multiple actions were found that match the request Web API
    基于REST架构的Web Service设计
    netbeans常用快捷键
    C#中 字符串转换为计算公式,并计算结果
    简谈asp.net下的异步加载
    简谈回顾多条件搜索查询。(适用于新手,老鸟飘过)
    简单回顾NPOI导入导出excel文件
    sql 中的Bulk和C# 中的SqlBulkCopy批量插入数据 ( 回顾 and 粗谈 )
    扩展lamda表达中distinct按照字段去除重复
    log4Net(写入日志文件)
  • 原文地址:https://www.cnblogs.com/qq874455953/p/10264428.html
Copyright © 2020-2023  润新知