eID Android SDK — интеграцийн гарын авлага¶
Android аппликейшнд eID (Gerege Smart-ID) бүртгэл (enroll), нэвтрэлт (authentication) ба
цахим гарын үсэг (signature)-ийг нэмэх developer гарын авлага. SDK нь Go backend (server/)-тэй
харьцаж, распределённый keygen + 2-of-2 threshold ECDSA-г утасны талд гүйцэтгэнэ. Крипто цөм
нь Kotlin-д бие даасан хэрэгжүүлэлт бөгөөд Go серверийн internal/crypto-той golden-vector-аар
байт-нийцтэй.
Package:
mn.eidmongolia.smartid· Client class:GeregeSmartIdClient· Module::android-sdk(Android library,.aar).
1. Товч танилцуулга¶
SDK нь дараах өндөр түвшний үйлдлүүдийг нэг GeregeSmartIdClient-ээр хийнэ:
| Үйлдэл | Функц | Тайлбар |
|---|---|---|
| Бүртгэл | enroll(...) |
KYC consent + distributed keygen → 2 сертификат (signing PIN2, authentication PIN1) |
| Session зөвшөөрөх | approve(...) |
Push/QR-аас ирсэн session-ийг threshold ECDSA-аар зурж баталгаажуулах |
| PIN шалгах | verifyPIN(...) / pinUnlocksSlot(...) |
Хадгалсан identity-г PIN-ээр тайлж шалгах (сервер рүү хандахгүй) |
| PIN солих | changePIN(...) |
Хуучин PIN-ээр тайлж, шинэ PIN-ээр дахин шифрлэх |
| KYC | danInit/danStatus/danLiveness, gsignInit/gsignVerify, passportInit |
DAN / G-Sign / гадаад паспортын баталгаажуулалт |
| Dashboard | pendingSign/pendingSession/recentActivity/sessionInfo |
Хүлээгдэж буй хүсэлт + сүүлийн үйл ажиллагаа |
2 сертификат нэг иргэнд. Enroll нь keygen-ийг ХОЁР удаа ажиллуулна: Authentication (PIN1, нэвтрэлт) ба Signing (PIN2, хууль ёсны гарын үсэг). Хувийн түлхүүр хэзээ ч нэг дор бүрэн байдаггүй — нэг хувь утсанд, нэг хувь серверт.
2. Урьдчилсан нөхцөл¶
- minSdk 24, targetSdk 35, JDK 17, Kotlin 1.9.24 (SDK build:
compileSdk 34). - Play Integrity attestation — хүсэлт бүрд серверийн nonce дээр шинэ token авна.
Апп-ийн
applicationIdба Google Cloud project (cloudProjectNumber) нь серверт бүртгэлтэй байх ёстой. - Backend URL — default
https://rp-api.eidmongolia.mn(config-оор солигдоно, доор үз).
(!) Эмулятор дээр Play Integrity ажиллахгүй. Go серверийг
SMARTID_REQUIRE_ATTESTATION=false(dev default)-оор ажиллуул — апп attestation-гүйгээр үргэлжилнэ. Эмулятор / Play Services байхгүй орчинд SDK ньAttestationUnavailableException-ийг зөөлөн барьж attestation-гүй үргэлжилнэ; жинхэнэ төхөөрөмж дээрх attestation алдаа (tamper/network) нь fail-closed (хүсэлт цуцлагдана).
3. Суулгах¶
SDK нь :android-sdk Gradle module хэлбэрээр орно (Maven coordinate-аар нийтлэгдээгүй — repo дотор
зэргэлдээ module эсвэл .aar-аар). Жишээ апп нь settings.gradle.kts-д зэргэлдээ module болгож оруулдаг:
// eIDMongolia/settings.gradle.kts
include(":app")
include(":android-sdk")
project(":android-sdk").projectDir = file("../android-sdk") // android/android-sdk
SDK өөрөө дараах хамааралтай (transitively орж ирнэ): com.google.android.play:integrity,
androidx.security:security-crypto (EncryptedSharedPreferences), com.squareup.okhttp3:okhttp,
kotlinx-coroutines-android + -play-services.
Биометр (заавал апп талд). Keystore auth-required түлхүүрийг зөвшөөрүүлэхэд апп нь
BiometricPrompt (FragmentActivity) хэрэгтэй тул апп-даа биометр dependency нэмнэ:
// app/build.gradle.kts
implementation("androidx.fragment:fragment-ktx:1.8.2")
implementation("androidx.biometric:biometric:1.1.0") // BiometricPrompt → FragmentActivity шаарддаг
Апп-ийн
MainActivityньFragmentActivity(эсвэлAppCompatActivity) байх ёстой — BiometricPrompt үүнийг шаардана.
4. Тохиргоо — backend URL¶
Апп нь backend суурь URL-ийг build үед BuildConfig.GEREGE_BACKEND_URL-д шигтгэнэ. Утгыг
gerege.backendUrl gradle property-аас авч, хоосон бол default руу унана:
// app/build.gradle.kts (defaultConfig)
val backendUrl = (project.findProperty("gerege.backendUrl") as String?)
?.takeIf { it.isNotBlank() } ?: "https://rp-api.eidmongolia.mn"
buildConfigField("String", "GEREGE_BACKEND_URL", "\"$backendUrl\"")
Тохируулах хоёр арга:
# 1) Command line property:
./gradlew :app:assembleDebug -Pgerege.backendUrl=https://<go-backend>
# 2) эсвэл eIDMongolia/gradle.properties-д:
# gerege.backendUrl=https://smartid-staging.example.mn
Аппликейшнд AppConfig-оор уншина:
object AppConfig {
val backendUrl: String get() = BuildConfig.GEREGE_BACKEND_URL
const val cloudProjectNumber: Long = 399766783708L // Google Cloud project (Play Integrity)
}
Локал Go сервер (http) руу холбогдвол
network_security_config-д cleartext зөвшөөрөл хэрэгтэй (LAN тест). Нийтийн host дээр SDK нь TLS-ийг Let's Encrypt root-д пинлэдэг; localhost/.local/ private-IP дээр пиннинг автоматаар алгасна.
5. Үндсэн ашиглалт¶
5.1 Client үүсгэх¶
val client = GeregeSmartIdClient(
context = this, // Context (Activity/Application)
baseUrl = AppConfig.backendUrl, // BuildConfig.GEREGE_BACKEND_URL
cloudProjectNumber = AppConfig.cloudProjectNumber, // Play Integrity
account = "default", // (сонголт) keystore slot нэр
)
5.2 Биометр authenticator (заавал)¶
approve / verifyPIN / changePIN зэрэг load-хийдэг үйлдлүүд нь Keystore-ийн
user-authentication-required түлхүүрийг задлахад BiometricAuthenticator-ийг шаарддаг. SDK нь UI
framework-аас хамааралгүй — апп нь BiometricPrompt-оор гүүр өгнө. Compose-д helper байдаг:
BiometricAuthenticator нь дараах гэрээтэй (SDK интерфейс):
interface BiometricAuthenticator {
suspend fun authenticate(cipher: Cipher, reason: String): Cipher
}
Хэрэглэгч цуцлах / биометр амжилтгүй → throw (fail-closed): unwrap/signing зогсоно, чимээгүй bypass байхгүй (iOS Secure Enclave
.userPresence-тэй parity).
5.3 Бүртгэл (enroll)¶
enroll нь KYC consent (danAuthCode) + PIN-ээр distributed keygen хийж, сертификат авч утсанд
хадгална. authPin өгвөл 2-cert (signing + authentication) хоёр тусдаа threshold түлхүүр үүснэ:
suspend fun enroll(
danAuthCode: String,
pin: CharArray, // PIN2 — signing (non-repudiation)
pushToken: String, // FCM token
authPin: CharArray? = null, // PIN1 — authentication (өгвөл 2-cert)
reviewLatin: (suspend (LatinNameProposal) -> Pair<String, String>?)? = null,
progress: ProgressHandler? = null,
): String // → documentNumber
val documentNumber = client.enroll(
danAuthCode = danCode,
pin = "1234".toCharArray(), // PIN2 (signing)
pushToken = fcmToken,
authPin = "5678".toCharArray(), // PIN1 (authentication)
)
Enroll нь дотроо серверийн keygen proof (rogue-key хамгаалалт) ба key-binding (гэрчилгээ ↔ joint Q = qClient+qServer) шалгалтыг хийдэг — сервер өөр түлхүүрт cert буцаавал хадгалахаас өмнө татгалзана.
Prewarm (сонголт). Бүртгэлийн дэлгэц нээгдэхэд
client.prewarmEnroll()-ийг дуудвал хүнд Paillier keygen-ийг background-д урьдчилан хийж, enroll-ийн хүлээлтийг багасгана.
5.4 Нэвтрэлт ба гарын үсэг (approve)¶
Push/QR-аас ирсэн sessionId-г PIN-ээр зөвшөөрнө. authentication = true бол auth түлхүүр (PIN1,
нэвтрэлт), эс бөгөөс sign түлхүүр (PIN2, гарын үсэг) ашиглана:
suspend fun approve(
sessionId: String,
pin: CharArray,
auth: BiometricAuthenticator,
authentication: Boolean = false, // true → PIN1/auth; false → PIN2/sign
confirmVc: String? = null, // хэрэглэгчийн баталсан verification code (WYSIWYS)
progress: ProgressHandler? = null,
): String // → status ("OK" гэх мэт)
// Нэвтрэлт (login):
val status = client.approve(sessionId, "5678".toCharArray(), auth, authentication = true)
// Гарын үсэг (sign):
val status = client.approve(sessionId, "1234".toCharArray(), auth)
approve дотор utас threshold ECDSA-ийн 3 round (commit → prove → finish)-ийг гүйцэтгэж, эцсийн
гарын үсгийг серверт илгээхээсээ өмнө session-ий мессежтэй (SIGN: digest; AUTH:
ACSP_V2(rpChallenge, SPKI)) таарч буйг бие даан ECDSA-verify хийдэг (WYSIWYS / transcript
binding). Таарахгүй бол гарын үсэг гарахгүй.
5.5 PIN шалгах / солих¶
suspend fun verifyPIN(slot: PINSlot, pin: CharArray, auth: BiometricAuthenticator): Boolean
suspend fun changePIN(slot: PINSlot, oldPin: CharArray, newPin: CharArray, auth: BiometricAuthenticator)
// slot: GeregeSmartIdClient.PINSlot.AUTH (PIN1) | .SIGN (PIN2)
Локал төлөв шалгах (сервергүй): hasRegistration(): Boolean, deleteRegistration().
5.6 KYC (богино)¶
Enroll-д хэрэгтэй danAuthCode-ийг авахын өмнө KYC-г SDK-аар гүйцэтгэнэ:
val (state, verifyUrl) = client.danInit(registrationNumber) // DAN verify URL
val verified = client.danStatus(state) // polling
val (passed, score) = client.danLiveness(state, selfieBytes) // face-match
Мөн gsignInit/gsignVerify (G-Sign), passportInit (гадаад паспорт) хувилбарууд байна — эх кодыг үз.
6. Түлхүүр хадгалалт ба биометр¶
SDK нь identity (xClient + Paillier private key + cert)-ийг PBKDF2(PIN)+AES-GCM-ээр шифрлэж
EncryptedSharedPreferences-д хадгалаад, дээр нь Android Keystore-ийн user-authentication-required
(биометр) түлхүүрээр давхар wrap хийдэг (offline PIN brute-force-ийг хаах, iOS Secure Enclave parity).
PIN болон x_client сервер рүү хэзээ ч очдоггүй.
Түлхүүр хадгалалт, RSA-OAEP wrap/unwrap, v1→v2 migration,
setInvalidatedByBiometricEnrollment, StrongBox fallback зэрэг гүн техник дэлгэрэнгүйг тусдаа баримтад бичсэн: Android biometric-gated keys.
7. Example app build / ажиллуулах¶
Урьдчилсан нөхцөл: ANDROID_HOME тохируулсан Android SDK; FCM push хэрэгтэй бол Firebase
төслийн жинхэнэ app/google-services.json (жишээ файл нь app/google-services.json.example).
cd android/eIDMongolia
# FCM push-д (сонголт): жинхэнэ Firebase файлаар солино
cp app/google-services.json.example app/google-services.json
# Debug APK — backend URL-ийг property-оор дамжуулна
./gradlew :app:assembleDebug -Pgerege.backendUrl=https://<go-backend>
# → app/build/outputs/apk/debug/app-debug.apk
Эсвэл Android Studio-д eIDMongolia-ийг нээж ажиллуулна. SDK library-г тусад нь угсрах:
cd android/android-sdk && gradle assembleRelease →
build/outputs/aar/...-release.aar.
google-services.jsonбайхгүй үед build тасрахгүй — апп компайл болж ажиллана (FCM push идэвхгүй; Play Integrity + enroll/approve нь google-services.json-гүйгээр ажиллана).
8. Апп ашигладаг Go backend endpoint-ууд¶
Бүгд Go серверийн internal/httpapi-д таарна (iOS-той ижил):
GET /v3/attestation/challenge— attestation noncePOST /v3/enrollment/init·/v3/enrollment/completeGET /v3/mobile/session/{id}·/v3/mobile/pending/{doc}·/v3/mobile/activity/{doc}POST /v3/mobile/session/{id}/sign/{commit,prove,finish}— 2-of-2 threshold ECDSA (3 round)- KYC:
/v3/kyc/dan/*,/v3/kyc/gsign/*
Сервер хариунд X-Next-Attestation-Nonce header өгдөг (SDK nonce-cache optimization).
9. Холбоос (эх сурвалж)¶
- Android SDK client:
https://github.com/gerege-systems/eid-platform-mn/blob/main/android/android-sdk/src/main/kotlin/mn/eidmongolia/smartid/GeregeSmartIdClient.kt - Keystore хадгалалт:
https://github.com/gerege-systems/eid-platform-mn/blob/main/android/android-sdk/src/main/kotlin/mn/eidmongolia/smartid/AndroidSecureKeyStore.kt - Biometric authenticator interface:
https://github.com/gerege-systems/eid-platform-mn/blob/main/android/android-sdk/src/main/kotlin/mn/eidmongolia/smartid/BiometricAuthenticator.kt - Example app entry point:
https://github.com/gerege-systems/eid-platform-mn/blob/main/android/eIDMongolia/app/src/main/kotlin/mn/eidmongolia/example/MainActivity.kt - Android README (build/run):
https://github.com/gerege-systems/eid-platform-mn/blob/main/android/README.md - SDK README (Kotlin архитектур):
https://github.com/gerege-systems/eid-platform-mn/blob/main/android/android-sdk/README.md - Биометр түлхүүр (гүн техник): ANDROID_BIOMETRIC_KEYS.md