Перейти к содержанию

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, чтобы пользователь сверил его с кодом на телефоне.

Используйте sessionID из ответа, чтобы открыть приложение из браузера:

geregesmartid://approve?sessionId=<sessionID>
Приложение откроется, и пользователь подтвердит операцию PIN1 (ключ аутентификации). Затем приложение вернётся на ваш 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/.