Skip to content

实现原理:离线 vs 在线分析

对应代码:pkg/offline.goNewOfflineAnalysis + FromCert 函数族)+ 在线函数分布于各模块

cert-skills 每个分析能力几乎都有"在线域名"和"离线证书"两个版本。本页讲这套双模架构的设计、函数签名与边界。

双模全景

离线入口

go
func NewOfflineAnalysis(cert *x509.Certificate, intermediates ...*x509.Certificate) *OfflineAnalysisResult

把已解析的证书 + 可选中间证书池(变长参数)包成结果,Target = cert.Subject.CommonName,构造 *x509.CertPool全程零网络

FromCert 函数签名表

函数签名底层调用
AnalyzeSecurityFromCert(cert *x509.Certificate, host string) (*SecurityAnalysis, error)转发 AnalyzeSecurityFromCertWithState(cert, host, nil)
AnalyzeSecurityFromCertWithState(cert, host string, state *tls.ConnectionState) (*SecurityAnalysis, error)ScanCertSecurityFromChain → 映射 issue → 离线评分
CheckDistrustedCAFromCert(chain []*x509.Certificate) *DistrustedCAResult遍历 chain,fingerprintCert + matchDistrustedCA
CheckKeyUsageFromCert(cert *x509.Certificate) *KeyUsageComplianceResult4 条规则内联,keyUsageToStrings/extKeyUsageToStrings
CheckPolicyFromCert(cert *x509.Certificate) *PolicyAnalysisResultcert.PolicyIdentifiers + knownPolicyOIDs + determineValidationType
CheckNameConstraintsFromCert(chain []*x509.Certificate) *NameConstraintsResultlen(chain)>=2collectLeafNames + extractCAConstraint
ScanCertSecurityFromChain(cert, host string, state *tls.ConnectionState) (*CertSecurityResult, error)18 项 certCheck(state==nil 时 12 项)

fingerprintCert(L328-334):GenerateFingerprints(cert)["sha256"],取不到返回 ""

共享核心

ScanCertSecurityFromChain 是两者共用核心——state==nil 自动只跑前 12 项。这套设计让离线模式复用同一套证书层规则,不重复实现。

离线 issue 映射

离线版把未通过检查直接映射成 issue(offline.go L55-64):

go
issue.Severity    = check.Severity
issue.Type        = check.Code      // 如 "CERT-005"
issue.Description = check.Name
issue.Impact      = check.Detail

然后用离线专属权重算分。

离线 vs 在线评分权重精确对比

维度在线(security.go L361-393)离线(offline.go L67-95)
Critical 扣分−30−25
High 扣分−20−15
Medium 扣分−10−5
Low 扣分−5−2
Good 阈值≥90≥80
Medium 阈值≥70≥60
Low 等级≥50—(无 Low 等级)
High 等级—(无 High 等级)≥40
Critical 阈值<50<40
起始分100100
下限00

关键差异:

  • 离线每级少扣 5 分(更宽容)
  • 等级阈值更严:Good 从 90 降到 80;离线无 "Low" 等级,多一个 "High" 等级覆盖 40-59
  • 同一张证书在 40-59 区间:在线判 Critical,离线判 High

设计哲学:宁可宽松,不误判

离线拿不到协议层信息,少了一大块扣分来源。所以离线权重每级少扣 5 分,等级阈值也更宽容——宁可偏宽松,也不因缺信息误判为高风险。这是诚实的工程权衡。

能做与不能做

CLI 如何路由:文件后缀自动切换

CLI 层用文件后缀自动路由(isFileTarget,helpers.go):

所以 cert-skills analyze ./server.pem 自动走离线,cert-skills analyze example.com 走在线——同一命令,双模自动切换

MCP 与 CLI 的不对称

MCP 工具大多只支持在线域名(需要 tls.ConnectionState)。离线文件分析请用 CLI 的文件路径模式(cert-skills analyze ./server.pem)。

离线场景

CI、取证、批量文件、历史证书——这些场景要么无网络,要么目标已下线。离线模式让同一套证书层规则在这些场景复用。

在线专属能力

以下必须在线,无离线版:

  • scan-vulns(漏洞扫描,需 raw TLS)
  • jarm / ja3(需握手)
  • check-hsts(需 HTTP 响应头)
  • check-caa(需 DNS 查询,但解析逻辑有 wire 离线版)
  • check-ocsp-must-staple(属协议层,需 OCSP staple)
  • check-revocation 的 OCSP 部分(CRL 部分可离线)

下一步