gerege.mn —— eID Gerege 集成(认证 · 签名 · 推送)¶
本指南介绍如何将 gerege.mn 作为 RP 接入 eID Gerege,通过 App2App(同设备)与
Push(跨设备)流程获得身份认证与电子签名能力。通信协议与 Smart-ID 兼容(ACSP_V2)。
RP 通用指南:RP_INTEGRATION.md。本文包含 gerege.mn 的实际配置与可直接复制的示例。
0. gerege.mn 的 RP 配置(已注册)¶
| 字段 | 取值 |
|---|---|
| relyingPartyUUID | 43a7bda9-0d68-4324-9ec1-3fc6dd8e4edf |
| relyingPartyName | gerege.mn |
| API secret(Bearer) | rp_sk_… —— 从运营方获取,保存在 $GEREGE_RP_SECRET 环境变量中(服务端仅保存 SHA-256 哈希) |
| RP-API 基础地址 | https://rp-api.eidmongolia.mn/v3 |
| 回调主机白名单 | gerege.mn、www.gerege.mn(App2App 返回 URL 必须是其中之一) |
| 应用 deep-link 协议 | geregesmartid://approve?sessionId=… |
| 服务发现 | GET https://rp-api.eidmongolia.mn/.well-known/eid |
每次调用均需:
- 请求头:Authorization: Bearer $GEREGE_RP_SECRET
- 请求体:relyingPartyUUID、relyingPartyName、certificateLevel(QUALIFIED)、signatureProtocol(ACSP_V2)
1. 身份认证 —— App2App(同设备,浏览器与应用位于同一部手机)¶
当用户用手机访问 gerege.mn 时:创建会话 → 通过 deep-link 打开应用 → 用户输入 PIN 确认 → 应用返回回调地址 → 轮询会话结果。
1.1 创建会话(携带 initialCallbackUrl)¶
curl -sS -X POST https://rp-api.eidmongolia.mn/v3/authentication/device-link/anonymous \
-H "Authorization: Bearer $GEREGE_RP_SECRET" -H "Content-Type: application/json" \
-d '{
"relyingPartyUUID": "43a7bda9-0d68-4324-9ec1-3fc6dd8e4edf",
"relyingPartyName": "gerege.mn",
"certificateLevel": "QUALIFIED",
"signatureProtocol": "ACSP_V2",
"initialCallbackUrl": "https://gerege.mn/auth/eid/callback?state=<csrf>",
"interactions": [{"type":"displayTextAndPIN","displayText60":"gerege.mn нэвтрэх"}]
}'
{ "sessionID": "…", "sessionToken": "…", "sessionSecret": "…",
"deviceLinkBase": "https://eidmongolia.mn/dl", "vc": "2025" }
⚠️
initialCallbackUrl的主机必须位于白名单中(gerege.mn/www.gerege.mn)—— 否则服务端会静默丢弃(防范开放重定向 / 钓鱼)。服务端仅保留 host 与 query, 并将路径强制规范化为/auth/eid/callback,因此请将 RP 的返回页面放在该路径下。 可将vc(4 位验证码)显示在 gerege.mn 页面上,供用户与手机上的验证码进行比对。
1.2 打开应用(deep-link)¶
使用响应中的 sessionID 从浏览器唤起应用:
initialCallbackUrl。
1.3 轮询结果 → 见 [§4]¶
2. 身份认证 —— Push(跨设备:用户位于另一台设备 / 电脑)¶
若您已知用户的登记号 / civil ID / 设备号,可直接向其手机发送推送。
# 使用 ETSI(PNOMN-<civilId>),或直接使用登记号 / civil ID 推送(服务端会自动识别类型)
curl -sS -X POST https://rp-api.eidmongolia.mn/v3/authentication/notification/etsi/PNOMN-<civilId> \
-H "Authorization: Bearer $GEREGE_RP_SECRET" -H "Content-Type: application/json" \
-d '{
"relyingPartyUUID": "43a7bda9-0d68-4324-9ec1-3fc6dd8e4edf",
"relyingPartyName": "gerege.mn",
"certificateLevel": "QUALIFIED",
"signatureProtocol": "ACSP_V2",
"interactions": [{"type":"displayTextAndPIN","displayText60":"gerege.mn нэвтрэх"}]
}'
# → { "sessionID": "…", "vc": { "type":"alphaNumeric4", "value":"2422" } }
vc.value 显示在 gerege.mn 页面上 —— 用户将其与手机收到的推送中的验证码比对后确认。
也可以按 document/{documentNumber}(设备 UUID)发送推送。
3. 电子签名(Signature)—— PIN2,不可否认¶
文档的 SHA-256 摘要(base64)在手机上使用 PIN2(签名密钥)完成签名。 手机会依据被签名的摘要计算 VC,因此用户看到的验证码即对应被签署的内容(WYSIWYS)。
3.1 通过 Push(跨设备)¶
DIGEST=$(sha256sum document.pdf | cut -d' ' -f1 | xxd -r -p | base64)
curl -sS -X POST https://rp-api.eidmongolia.mn/v3/signature/notification/document/<documentNumber> \
-H "Authorization: Bearer $GEREGE_RP_SECRET" -H "Content-Type: application/json" \
-d "{
\"relyingPartyUUID\": \"43a7bda9-0d68-4324-9ec1-3fc6dd8e4edf\",
\"relyingPartyName\": \"gerege.mn\",
\"certificateLevel\": \"QUALIFIED\", \"signatureProtocol\": \"ACSP_V2\",
\"digest\": \"$DIGEST\", \"hashType\": \"SHA256\",
\"interactions\": [{\"type\":\"displayTextAndPIN\",\"displayText60\":\"gerege.mn гарын үсэг\"}]
}"
# 通过 ETSI:/signature/notification/etsi/PNOMN-<civilId>
3.2 通过 App2App(同设备)¶
POST /v3/signature/device-link/document/{documentNumber} —— 请求体包含 digest、hashType、
initialCallbackUrl(gerege.mn),随后通过 geregesmartid://approve?sessionId=… 打开应用。
3.3 完成之后 —— PAdES PDF(可选)¶
一旦轮询返回 endResult=OK,即可对原始 PDF 加盖签章,下载内嵌验证页与
RFC 3161 时间戳的 PDF(PAdES-T):
curl -sS -X POST "https://rp-api.eidmongolia.mn/v3/signature/stamp/<sessionID>?fileName=document.pdf" \
-H "Authorization: Bearer $GEREGE_RP_SECRET" --data-binary @document.pdf -o signed.pdf
https://eidmongolia.mn/verify/<sessionID>(公开访问;二维码中也包含该链接)。
4. 轮询会话结果(长轮询)¶
curl -sS "https://rp-api.eidmongolia.mn/v3/session/<sessionID>?timeoutMs=120000" \
-H "Authorization: Bearer $GEREGE_RP_SECRET"
state=RUNNING —— 处理中(继续轮询)
- state=COMPLETE + result.endResult=OK →
- signature.value —— 分离式 ECDSA 签名(signature.signatureAlgorithm=ecdsa-with-SHA256)
- cert.value —— 公民的 X.509 证书(auth 或 sign),cert.certificateLevel
- state=COMPLETE + 其他 result.endResult(USER_REFUSED、TIMEOUT、WRONG_VC 等)→ 被拒绝
认证结果校验(gerege.mn 侧): 将返回的证书链接至 eID Gerege 根 CA
(OCSP:discovery 文档中的 endpoints.ocsp),并验证 rpChallenge(若已发送)已包含在签名中。
5. 安全要求(gerege.mn 侧)¶
initialCallbackUrl必须为https://+ 白名单主机(gerege.mn/www.gerege.mn)。 其他主机会被静默丢弃。- 在回调 URL 中带上
state(CSRF)参数,并在返回时进行校验。 - API secret 只能保存在后端(切勿暴露在浏览器中)。RP-API 调用为服务端到服务端。
- 向用户展示 VC 验证码以便与手机比对,可防止中间人钓鱼攻击。
- 轮询会话的 TTL 为 10 分钟(
SMARTID_SESSION_TTL_SECONDS)。
6. 流程简图(App2App 身份认证)¶
gerege.mn(浏览器) eID Gerege RP-API eID Gerege 应用(手机)
│ POST device-link/anonymous │ │
│ (+ initialCallbackUrl) ───▶ │ 创建会话(校验回调白名单) │
│ ◀── sessionID, vc │ │
│ geregesmartid://approve?sessionId=… ───────────────────────▶ │ 应用打开
│ │ │ PIN1 → 门限认证
│ │ ◀──── commit/prove/finish ─── │
│ ◀───────── 回调: https://gerege.mn/auth/eid/callback?state=… ── │ (返回)
│ GET session/{id}(轮询)───▶ │ │
│ ◀── COMPLETE, endResult=OK, cert ─│ │
可运行的客户端示例:web/src/lib/rpclient.ts(TypeScript),
或使用 sdk/typescript/ SDK。