之前示範過用 openssl s_client -connect www.google.com:443 -showcerts 指令取回網站的 TLS 憑證:(下圖 BEGIN CERTIFICATE 及 END CERTIFICATE 包夾的 Base64 編碼內容)

將這段文字複製出來存成 .cer 或 .crt,在 Windows 點兩下檔案可開啟憑證檢視器查看。

如果你也對如何從這段神祕編碼解析憑證資訊感到好奇,表示你是本篇文章的 TA,歡迎繼續讀下去。否則請關上網頁,把生命花在其他美好事物上。

先了解幾個名詞:

  • Privacy-Enhanced Mail,PEM 格式 儲存、傳輸金鑰、公開金鑰憑證和其他資料的檔案格式的業界標準,即用 -----BEGIN XXX---- 包夾 -----END XXX----- 的文字表示格式。
  • PKCS#* 標準
    Public Key Cryptography Standards, PKCS 是 RSA 實驗室定義的一系列公開公鑰相關標準。
    • PKCS#1 - RSA 密碼編譯標準,可用於表示 RSA 公私鑰(-----BEGIN RSA PRIVATE KEY----------BEGIN RSA PRIVATE KEY----------BEGIN RSA PUBLIC KEY-----)
    • PKCS#13 - 橢圓曲線密碼學標準,可用於表示 EC 私鑰(-----BEGIN EC PRIVATE KEY-----)
    • PKCS#8 - 私鑰訊息表示標準,通用私鑰標準,一般會先用 PKCS#5 PDBKDF2 加密再轉成 PEM (-----BEGIN PRIVATE KEY----------BEGIN ENCRYPTED PRIVATE KEY-----)
    • PKCS#7 - 密碼訊息語法標準,可交換簽章/密文,常用於郵件加密(S/MIME),Windows 附檔名 .p7b。(-----BEGIN PKCS7-----)
    • PKCS#12 - 個人訊息交換標準,包含私鑰與公鑰憑證(私鑰採密碼保護),副檔名為 .p12 或 .pfx。可視為 .PKCS#7 擴充,額外儲存憑證、私鑰及 CRL。常用於 HTTPS/TLS。(-----BEGIN PKCS12-----)
  • X.509 證書
    公鑰憑證的格式標準,包含公鑰、身分資訊(如網路主機名,組織名稱或個體名稱)和簽章資訊(憑證簽發機構 CA 的簽章或自簽章,常以 PEM 形式表示 (-----BEGIN CERTIFICATE-----)
  • ASN.1
    ASN.1 (Abstract Syntax Notation One) 是一套語法標準,可靈活表示結構化資料。ASN.1 本身只定義訊息的抽象語法,具體編碼細節另有 BER、CER、DER、PER、XER 等編碼規則定義,電子憑證與簽章最常用的編碼規則是 DER Distinguished Encoding Rules。

以文章開始提到的憑證 PEM 為例,Base64 編碼的內容是 ASN.1 語法表示的 X.509 憑證資料。

要解析 ASN.1 內容,最方便的工具是 ASN.1 JavaScript decoder,將 PEM 內容貼到網頁上,憑證內容會被詳細拆解,滑鼠移到特定欄位值還會對映顯示二進位資料的所在位置,解析結果還能透過連結分享,大家可以實際操作看看

ASN.1 是一種巢狀結構,以層層 Tag 識別、長度、資料形式層層套疊,還包含一些複雜位元組合規則以節省位元數。在解讀憑證資料時,主角是 2.5.29.15 這些 OID (Object Identifier),可以想像成類似 Domain Name 的全球唯一標識。以 2.5.29.15 為例:

  • 2:ISO 分配的根節點
  • 5:ISO 國家分配
  • 29:X.509 證書擴展(Extension)
  • 15:特定擴展(在此為 keyUsage)

Global OID reference database 可以查到全世界所有 OID,要研究 X.509 憑證可查詢 2.5.29 所屬 OID 列表

以下是憑證欄位層級結構及值:(使用 openssl asn1parse -in google.cer 也可取得欄位資訊,但較難對映 ASN.1 結構)

tbsCertificate
version 版本號
- Value: 2
serialNumber 序號
- Value: (127 bit) 159065829549671771046114131679853313918 **[1]**
signature
    algorithm 簽章演算法
    - Value: 1.2.840.113549.1.1.11 (sha256WithRSAEncryption, PKCS #1)
      - SHA-256 與 RSA 加密(PKCS #1)- 用於數位簽名
issuer
    RelativeDistinguishedName (1)
        type
        - Value: 2.5.4.6 (countryName, X.520 DN component)
          - 國家名稱(X.520 識別名稱組件)- 證書中國家的名稱
        value
        - Value: US
          - 美國
    RelativeDistinguishedName (2)
        type
        - Value: 2.5.4.10 (organizationName, X.520 DN component)
          - 組織名稱(X.520 識別名稱組件)- 證書中組織的名稱
        value
        - Value: Google Trust Services
    RelativeDistinguishedName (3)
        type
        - Value: 2.5.4.3 (commonName, X.520 DN component)
          - 公共名稱(X.520 識別名稱組件)- 證書中實體的公共名稱
        value
        - Value: WR2
          - WR2
validity
    notBefore
    - Value: 2025-01-06 08:37:56 UTC
      - 有效期自
    notAfter
    - Value: 2025-03-31 08:37:55 UTC
      - 有效期到
subject
    type
    - Value: 2.5.4.3 (commonName, X.520 DN component)
      - 公共名稱(X.520 識別名稱組件)- 證書中實體的公共名稱
    value
    - Value: www.google.com
subjectPublicKeyInfo
    algorithm
        algorithm 
        - Value: 1.2.840.10045.2.1 (ecPublicKey, ANSI X9.62 public key type)
          - ecPublicKey(ANSI X9.62 公鑰類型)- 用於橢圓曲線加密的公鑰類型
        parameters 公開金鑰參數 ECDSA_P256
        - Value: 1.2.840.10045.3.1.7 (prime256v1, ANSI X9.62 named elliptic curve)
          - prime256v1(ANSI X9.62 命名橢圓曲線)- prime256v1 橢圓曲線參數
    subjectPublicKey 公開金鑰
    - Value: (520 bit) 0000010010011110...
      - 主體公鑰
extensions
    Extension (1) - keyUsage
        extnID
        - Value: 2.5.29.15 (keyUsage, X.509 extension)
          - 金鑰使用方法(X.509 擴充)- 定義證書金鑰的用途
        critical
        - Value: true
        extnValue
        - Value: 03020780
          - Encapsulated: BIT STRING (1 bit) 1 = 80
    Extension (2) - extKeyUsage
        extnID
        - Value: 2.5.29.37 (extKeyUsage, X.509 extension)
          - 增強金鑰用途(X.509 擴充)- 定義證書金鑰的額外用途
        extnValue
        - Value: 300A06082B06010505070301
          - Encapsulated: SEQUENCE (1 element)
            - Value: 1.3.6.1.5.5.7.3.1 (serverAuth, PKIX key purpose)
            - 伺服器驗證(PKIX 金鑰用途)- 用於伺服器身份驗證
    Extension (3) - basicConstraints
        extnID
        - Value: 2.5.29.19 (basicConstraints, X.509 extension)
          - 基本限制(X.509 擴充)- 定義證書是否為 CA 並限制其層級
        critical
        - Value: true
        extnValue
        - Value: 3000
          - Encapsulated: SEQUENCE (0 elements)
    Extension (4) - subjectKeyIdentifier
        extnID
        - Value: 2.5.29.14 (subjectKeyIdentifier, X.509 extension)
          - 主體金鑰識別碼(X.509 擴充)- 識別證書主體的金鑰
        extnValue
        - Value: 0414F3102801C586873FC0473A7A4D6BA5C9011C9DF4
          - Encapsulated: OCTET STRING (20 byte) F3102801C586873FC0473A7A4D6BA5C9011C9DF4 **[2]**
    Extension (5) - authorityKeyIdentifier
        extnID
        - Value: 2.5.29.35 (authorityKeyIdentifier, X.509 extension)
          - 授權單位金鑰識別元(X.509 擴充)- 識別簽發證書的權威金鑰
        extnValue
        - Value: 30168014DE1B1EED7915D43E3724C321BBEC34396D42B230
          - Encapsulated: SEQUENCE (1 element)
            - Value: DE1B1EED7915D43E3724C321BBEC34396D42B230 **[3]**
    Extension (6) - authorityInfoAccess
        extnID
        - Value: 1.3.6.1.5.5.7.1.1 (authorityInfoAccess, PKIX private extension)
          - 授權單位存取(PKIX 私有擴充)- 提供存取簽發證書權威資訊的方法
        extnValue
        - Value: 304A302106082B060105050730018615687474703A2F2F6F2E706B692E676F6F672F777232...
          - Encapsulated: SEQUENCE (2 elements)
            - Element 1: SEQUENCE (2 elements)
              - Value: 1.3.6.1.5.5.7.48.1 (ocsp, PKIX OCSP)
                - OCSP(PKIX 線上證書狀態協議)- 用於證書撤銷狀態查詢
              - Value: http://o.pki.goog/wr2
                - http://o.pki.goog/wr2
            - Element 2: SEQUENCE (2 elements)
              - Value: 1.3.6.1.5.5.7.48.2 (caIssuers, PKIX subject/authority info access descriptor)
                - CA 發行者(PKIX 主體/權威資訊存取描述符)- 提供 CA 的發行者資訊
              - Value: http://i.pki.goog/wr2.crt
                - http://i.pki.goog/wr2.crt
    Extension (7) - subjectAltName
        extnID
        - Value: 2.5.29.17 (subjectAltName, X.509 extension)
          - 主體別名(X.509 擴充)- 定義證書主體的額外名稱
        extnValue
        - Value: 3010820E7777772E676F6F676C652E636F6D
          - Encapsulated: SEQUENCE (1 element)
            - Value: www.google.com
    Extension (8) - certificatePolicies
        extnID
        - Value: 2.5.29.32 (certificatePolicies, X.509 extension)
          - 憑證原則(X.509 擴充)
        extnValue
        - Value: 300A3008060667810C010201
          - Encapsulated: SEQUENCE (1 element)
            - Value: 2.23.140.1.2.1 (domainValidated, CAB Certificate Policies)
              - 網域驗證(CAB 證書政策)- 用於網域驗證證書的政策識別符
    Extension (9) - cRLDistributionPoints
        extnID
        - Value: 2.5.29.31 (cRLDistributionPoints, X.509 extension)
          - CRL 發佈點(X.509 擴充)- 定義證書撤銷列表(CRL)的分發點
        extnValue
        - Value: 302D302BA029A0278625687474703A2F2F632E706B692E676F6F672F7772322F373572...
          - Encapsulated: SEQUENCE (1 element)
            - Value: http://c.pki.goog/wr2/75r4ZyA3vA0.crl
    Extension (10) - googleSignedCertificateTimestamp
        extnID
        - Value: 1.3.6.1.4.1.11129.2.4.2 (googleSignedCertificateTimestamp, Google Certificate Transparency)
          - Google Signed Certificate Timestamp(Google 證書透明度)- 用於證書透明度的時間戳,SCT 清單 
        extnValue 
        - Value: 0481F100EF007500 CCFB0F6A85710965FE959B53CEE9B27C22E9855C0D978DB6A97E5... **[4]**
signatureAlgorithm
algorithm 
- Value: 1.2.840.113549.1.1.11 (sha256WithRSAEncryption, PKCS #1)
  - SHA-256 與 RSA 加密(PKCS #1)- 用於數位簽名
parameters
signature
Value: (2048 bit) 001001101000001010100111100101000110101001101011101111101111010000110…
  - 簽名

以上內容可跟 Winows 憑證檢視的各欄位一一對映上:(見 **[N]** 標註位置)

  • [1] 序號 159065829549671771046114131679853313918 轉 16 進位 77aaf6e49cd0fc60094126dfd21e7f7e
    const decimalValue = '159065829549671771046114131679853313918';
    const bigIntValue = BigInt(decimalValue);
    const hexValue = bigIntValue.toString(16); // 將結果轉成大寫
    console.log(hexValue); // 輸出:77AAF6E49CD0FC60094126DFD21E7F7E
    
  • [2] 主體金鑰識別碼 f3102801c586873fc0473a7a4d6ba5c9011c9df4
  • [3] 授權單位金鑰識別元 de1b1eed7915d43e3724c321bbec34396d42b230
  • [4] SCT 清單 ccfb0f6a85710965fe959b53cee9b27c22e9855c0d978db6a97e5...

至於憑證指紋是將整個 DER byte[] 做 SHA1:

用 PowerShell 計算:

或用 openssl x509 -in google.pem -fingerprint -sha1

拼上最後一塊拼圖,完美! 收工。

【擴充閱讀】


Comments

Be the first to post a comment

Post a comment