本文主要内容由 ChatGPT 生成
伸手党可以直接跳过全文,下载脚本:acme-free

📖 什么是 ACME?

ACME(Automatic Certificate Management Environment)是由 Let’s Encrypt 提出,并由 IETF RFC 8555 标准化的协议。

它允许客户端自动完成 HTTPS 证书的:

  • 申请(Order)
  • 域名验证(Authorization & Challenge)
  • 签发与下载(Certificate)

🧱 核心概念

概念 含义
Account 注册者账户,标识用户(通过公钥)
Order 一次申请证书的请求,包含多个域名
Authorization 每个域名对应的授权验证流程
Challenge 实际用于验证的方式,如 DNS-01、HTTP-01、TLS-ALPN-01
Finalize 提交 CSR 的步骤,表明已完成所有验证
Certificate 最终由 CA 签发的证书内容

✅ 完整的证书申请流程(以 DNS-01 为例)

1. 创建账户

1
POST /acme/new-acct
  • 客户端生成一对密钥
  • 使用 JWS(带签名的 JSON)请求创建账户
  • 返回 Account URL

2. 创建 Order(订单)

1
POST /acme/new-order
1
2
3
4
5
6
{
"identifiers": [
{ "type": "dns", "value": "example.com" },
{ "type": "dns", "value": "www.example.com" }
]
}
  • 返回一个 Order 对象,包含:
    • Authorization URL(每个域名一个)
    • Finalize URL(CSR 提交用)

3. 获取 Authorization(验证信息)

1
GET /acme/authz/XXX
  • 包含一个或多个 Challenge
    • DNS-01
    • HTTP-01
    • TLS-ALPN-01

4. 响应 Challenge

以 DNS-01 为例:

1
2
记录名:_acme-challenge.example.com
记录值:(token + account key 生成的值)

客户端发起:

1
POST /acme/challenge/XYZ

表示“我准备好了”,等待验证生效。


5. 等待验证通过

1
GET /acme/authz/XYZ
  • 轮询直到状态为 "valid""invalid"

6. Finalize 订单(提交 CSR)

1
POST /acme/finalize/XYZ
  • 提交你的 CSR(证书签名请求)
  • 返回的 Order 状态变为 valid,并附带 Certificate URL

7. 下载证书

1
GET /acme/cert/XYZ
  • 获取 PEM 格式的证书链(包含 leaf cert + CA cert)

🔄 可恢复流程说明

ACME 支持流程中断恢复:

  • 保存 Account URL(标识你是谁)
  • 保存 Order URL(可以重复访问)
  • 保存 Authorization/Challenge 状态
  • 没有状态超时的步骤可以按需恢复继续执行

📦 推荐实现方式

Go 实现库 控制级别 说明
lego 封装全面,支持多 DNS 服务商
golang.org/x/crypto/acme 极高 原生协议控制,适合定制验证流程和持久化恢复等高级功能

🔄 流程图(简化)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
+---------+      +-------------+     +---------------+
| Client | ---> | newAccount | --> | Account |
+---------+ +-------------+ +---------------+

+---------+ +-------------+ +---------------+
| Client | ---> | newOrder | --> | Order |
+---------+ +-------------+ +--------+------+
|
+---------v----------+
| Authorization[] |
+----------+----------+
|
+------------v-------------+
| Challenge[] |
+------------+--------------+
|
+------------------v------------------+
| 完成验证:DNS/HTTP 上传数据 |
+------------------+------------------+

+---------+ +-------------+ +---------------+
| Client | ---> | finalize | --> | Order(Ready) |
+---------+ +-------------+ +-------+-------+
|
+---------v----------+
| Get Certificate |
+---------------------+

✅ 总结

如果你需要:

  • 🔄 支持中断恢复
  • 🎯 精确控制每个步骤
  • 💾 本地持久化订单、认证、挑战状态

推荐使用:

1
import "golang.org/x/crypto/acme"

配合手动实现持久化与控制逻辑,可获得最大自由度。

vibe coding

最后也体验了一把 vibe coding,实现了一个自助申请证书的脚本:acme-free