证书详情解析
GetCertificateByID 是 SDK 里最"重"的方法——crt.sh 的 ?id= 端点只返回 HTML,没有 JSON,所有字段都得从 HTML 里抠出来。
为什么这一步最难
flowchart LR ID["crt.sh ID
如 12345"] --> REQ["GET crt.sh?id=12345"] REQ --> HTML["一大张 HTML 表格"] HTML --> P["parseCertDetailHTML
一串正则"] P --> D["CertificateDetail 结构体
SHA指纹/SKI/SAN/SCT/吊销/..."]
如 12345"] --> REQ["GET crt.sh?id=12345"] REQ --> HTML["一大张 HTML 表格"] HTML --> P["parseCertDetailHTML
一串正则"] P --> D["CertificateDetail 结构体
SHA指纹/SKI/SAN/SCT/吊销/..."]
crt.sh 的详情页是一张嵌套 HTML 表格,字段靠 <TH>字段名</TH><TD>值</TD> 的位置约定。SDK 用一组针对性正则把每个字段单独抠出来——这是 parser.go 的职责。
解析出的字段
🆔ID / Summary
parseCertID / parseSummary
🔐SHA-256 / SHA-1
parseSHA256 / parseSHA1
🔑SPKI SHA-256
parseSPKISHA256(从 ?spkisha256= 链接)
📜CT 条目
parseCTEntries(4 列表格行)
🚫吊销记录
parseRevocations(6 列或 3 列表格行)
📝序列号/CN/签发者
parseCertText + 子正则
🏛️issuer CA ID
extractIssuerCAID(CA ID: \d+)
📅有效期
parseValidityFromText
三个可选视图
GetCertificateByID(ctx, id, opts) 接受 CertDetailOptions,对应 crt.sh 的 ?opt= 参数:
| 选项 | URL | 含义 |
|---|---|---|
NoMetadata | ?opt=nometadata | 去掉元数据,只看证书本体 |
OCSPCheck | ?opt=ocsp | 触发 OCSP 实时核验 |
Pkimetal | ?opt=pkimetal | 触发 PKI Metal lint |
按想看的侧重点选 opt:
flowchart TD GOAL["你想看什么?"] --> Q1{只要证书本体,
嫌元数据干扰?} Q1 -->|是| NM["NoMetadata
?opt=nometadata"] Q1 -->|否| Q2{要看实时吊销状态?} Q2 -->|是| OCSP["OCSPCheck
?opt=ocsp"] Q2 -->|否| Q3{要 PKI 合规体检?} Q3 -->|是| PKM["Pkimetal
?opt=pkimetal"] Q3 -->|否| DEF["不传 opt
默认详情"]
嫌元数据干扰?} Q1 -->|是| NM["NoMetadata
?opt=nometadata"] Q1 -->|否| Q2{要看实时吊销状态?} Q2 -->|是| OCSP["OCSPCheck
?opt=ocsp"] Q2 -->|否| Q3{要 PKI 合规体检?} Q3 -->|是| PKM["Pkimetal
?opt=pkimetal"] Q3 -->|否| DEF["不传 opt
默认详情"]
go
// 实时核验吊销状态
detail, _ := client.GetCertificateByID(ctx, 12345, crtsh.WithOCSPCheck())容错设计
宽容解析
parseCertDetailHTML 对畸形输入不报错,只返回已成功解析的字段。crt.sh 的 HTML 结构会随版本微调,让解析器"崩了就全丢"太脆弱。缺失字段在结构体里保持零值,调用方按需判空。
比搜索结果 richer
flowchart LR subgraph 搜索["Certificate(搜索)"] A1["id / not_before / not_after
name_value / issuer_name 等核心字段"] end subgraph 详情["CertificateDetail(详情)"] B1["SHA 指纹 / SKI / SAN 列表
CT 条目(日志名/时间)/ SCT
吊销记录 / 签名算法 / 密钥大小"] end 搜索 -.->|"GetCertificateByID"| 详情
name_value / issuer_name 等核心字段"] end subgraph 详情["CertificateDetail(详情)"] B1["SHA 指纹 / SKI / SAN 列表
CT 条目(日志名/时间)/ SCT
吊销记录 / 签名算法 / 密钥大小"] end 搜索 -.->|"GetCertificateByID"| 详情
下一篇