gerege.mn — интеграция с eID Gerege (auth · sign · push)¶
Руководство по подключению gerege.mn в качестве RP к eID Gerege для получения
аутентификации и электронной подписи через сценарии App2App (same-device) и
Push (cross-device). Протокол совместим со Smart-ID (ACSP_V2).
Общее руководство по RP: RP_INTEGRATION.md. В этом файле — фактическая конфигурация gerege.mn и примеры для копирования.
0. Конфигурация RP gerege.mn (зарегистрирована)¶
| Поле | Значение |
|---|---|
| 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 |
| Белый список хостов callback | gerege.mn, www.gerege.mn (URL возврата App2App должен быть одним из них) |
| Схема deep-link приложения | geregesmartid://approve?sessionId=… |
| Discovery | GET https://rp-api.eidmongolia.mn/.well-known/eid |
В каждом вызове:
- Заголовок: Authorization: Bearer $GEREGE_RP_SECRET
- Тело: relyingPartyUUID, relyingPartyName, certificateLevel (QUALIFIED), signatureProtocol (ACSP_V2)
1. Аутентификация — App2App (same-device, браузер и приложение на одном телефоне)¶
Когда пользователь заходит на gerege.mn с телефона: создать сессию → открыть приложение по deep-link → пользователь подтверждает PIN-кодом → приложение возвращается на callback → опросить результат сессии.
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) — иначе сервер молча его отбрасывает (защита от open-redirect/фишинга). Сервер сохраняет только host и query, а путь принудительно нормализуется к/auth/eid/callback, поэтому разместите страницу возврата RP именно по этому пути. Значениеvc(4-значный код) можно показать на экране gerege.mn, чтобы пользователь сверил его с кодом на телефоне.
1.2 Открытие приложения (deep-link)¶
Используйте sessionID из ответа, чтобы открыть приложение из браузера:
initialCallbackUrl.
1.3 Опрос результата → [§4]¶
2. Аутентификация — Push (cross-device: пользователь на другом устройстве/компьютере)¶
Если вы знаете пользователя по регистрационному номеру / civil ID / документу, отправьте push на его телефон.
# 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 — пользователь сверит его с кодом в полученном push-уведомлении
и подтвердит. Push можно отправить и по document/{documentNumber} (UUID устройства).
3. Электронная подпись (Signature) — PIN2, неотказуемость¶
SHA-256 дайджест документа (base64) подписывается на телефоне с помощью PIN2 (ключ подписи). Телефон вычисляет VC из подписываемого дайджеста, поэтому код, который видит пользователь, соответствует подписываемому содержимому (WYSIWYS).
3.1 Через Push (cross-device)¶
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 (same-device)¶
POST /v3/signature/device-link/document/{documentNumber} — тело с digest, hashType,
initialCallbackUrl (gerege.mn), затем открыть приложение через geregesmartid://approve?sessionId=….
3.3 После завершения — PAdES PDF (опционально)¶
Как только опрос вернёт endResult=OK, проштампуйте исходный PDF и скачайте PDF со встроенной
страницей валидации и меткой времени RFC 3161 (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> (публичная; также в QR-коде).
4. Опрос результата сессии (long-poll)¶
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): выстройте цепочку возвращённого сертификата
до корневого CA eID Gerege (OCSP: endpoints.ocsp из discovery-документа) и убедитесь, что
rpChallenge (если он отправлялся) включён в подпись.
5. Требования безопасности (на стороне gerege.mn)¶
initialCallbackUrlдолжен бытьhttps://+ хост из белого списка (gerege.mn/www.gerege.mn). Другие хосты молча отбрасываются.- Включайте параметр
state(CSRF) в callback-URL и проверяйте его при возврате. - Храните API secret только на бэкенде (никогда не раскрывайте его в браузере). Вызовы RP-API выполняются server-to-server.
- Показ VC-кода пользователю для сверки с телефоном защищает от атак «рыбак посередине».
- TTL сессии для опроса — 10 минут (
SMARTID_SESSION_TTL_SECONDS).
6. Краткая схема потока (аутентификация App2App)¶
gerege.mn (браузер) eID Gerege RP-API приложение eID Gerege (телефон)
│ POST device-link/anonymous │ │
│ (+ initialCallbackUrl) ───▶ │ создание сессии (проверка │
│ ◀── sessionID, vc │ белого списка callback) │
│ geregesmartid://approve?sessionId=… ───────────────────────▶ │ приложение открывается
│ │ │ PIN1 → пороговая аутентификация
│ │ ◀──── commit/prove/finish ─── │
│ ◀───────── callback: https://gerege.mn/auth/eid/callback?state=… ── │ (возврат)
│ GET session/{id} (опрос) ──▶ │ │
│ ◀── COMPLETE, endResult=OK, cert ─│ │
Пример рабочего клиента: web/src/lib/rpclient.ts (TypeScript),
либо SDK sdk/typescript/.