From 870d3eb0f619635989d7c298bed9207fc6c13770 Mon Sep 17 00:00:00 2001 From: Shihaam Abdul Rahman Date: Fri, 23 Oct 2026 03:09:42 +0500 Subject: [PATCH] MIB v2 login works --- .../sh/sar/basedbank/api/mib/MibLoginFlow.kt | 19 ++++++- docs/mibapi/02-login.md | 12 +++- docs/mibapi/README.md | 2 +- docs/mibapi/upgradev2.md | 57 ++++++++++++------- 4 files changed, 64 insertions(+), 26 deletions(-) diff --git a/app/src/main/java/sh/sar/basedbank/api/mib/MibLoginFlow.kt b/app/src/main/java/sh/sar/basedbank/api/mib/MibLoginFlow.kt index 42afed7..e2d08e7 100644 --- a/app/src/main/java/sh/sar/basedbank/api/mib/MibLoginFlow.kt +++ b/app/src/main/java/sh/sar/basedbank/api/mib/MibLoginFlow.kt @@ -7,6 +7,10 @@ import okhttp3.OkHttpClient import okhttp3.Request import org.json.JSONObject import java.security.MessageDigest +import java.text.SimpleDateFormat +import java.util.Date +import java.util.Locale +import java.util.TimeZone import java.util.concurrent.TimeUnit import java.util.concurrent.atomic.AtomicBoolean import kotlin.math.abs @@ -16,7 +20,7 @@ class SessionExpiredException : Exception("MIB session expired") class MibLoginFlow(private val credentialStore: CredentialStore) { - private val BASE_URL = "https://faisanet.mib.com.mv/faisamobilex_smvc/" + private val BASE_URL = "https://faisamobilex-smvc-v2.mib.com.mv/index/" /** The active session after a successful login, usable for subsequent WebView requests. */ var lastSession: MibSession? = null @@ -42,8 +46,9 @@ class MibLoginFlow(private val credentialStore: CredentialStore) { .writeTimeout(30, TimeUnit.SECONDS) .addNetworkInterceptor { chain -> val req = chain.request().newBuilder() - .header("User-Agent", "android/1.0") + .header("User-Agent", "android/2.0") .header("Accept", "application/json") + .header("X-Request-ID", generateRequestId()) .header("Content-Type", "application/x-www-form-urlencoded; charset=utf-8") .build() chain.proceed(req) @@ -424,6 +429,16 @@ class MibLoginFlow(private val credentialStore: CredentialStore) { return sha256Upper(clientSalt + h2) } + private fun generateRequestId(): String { + val sdf = SimpleDateFormat("yyyyMMddHHmmss", Locale.US).apply { + timeZone = TimeZone.getTimeZone("UTC") + } + val timestamp = sdf.format(Date()) + val millis = System.currentTimeMillis() % 1000 + val randomHex = Random.nextBytes(8).joinToString("") { "%02x".format(it) } + return "$timestamp${millis.toString().padStart(3, '0')}-$randomHex" + } + companion object { /** Returns SHA-256(password) as uppercase hex. Store this instead of the raw password. */ fun hashPassword(password: String): String = diff --git a/docs/mibapi/02-login.md b/docs/mibapi/02-login.md index 9c1bd77..006ef04 100644 --- a/docs/mibapi/02-login.md +++ b/docs/mibapi/02-login.md @@ -57,6 +57,16 @@ def compute_pgf03(password: str, user_salt: str, client_salt: str) -> str: ## Step-by-Step Reference +**Endpoint**: `POST https://faisamobilex-smvc-v2.mib.com.mv/index/` + +**Headers** (on all requests): +``` +User-Agent: android/2.0 +Accept: application/json +X-Request-ID: {YYYYMMDDHHmmss}{milliseconds}-{16-char-hex} +Content-Type: application/x-www-form-urlencoded; charset=utf-8 +``` + ### [0] Initial Key Exchange — `sfunc=r` **Key**: `DEFAULT_KEY = 8M3L9SBF1AC4FRE56788M3L9SBF1AC4FRE5678` @@ -67,7 +77,7 @@ def compute_pgf03(password: str, user_salt: str, client_salt: str) -> str: "sfunc": "r", "data": { "cmod": "", - "appId": "IOS17.2-<15 random alphanumeric chars>", + "appId": "AND34-<15 random alphanumeric chars>", "routePath": "S40", "sodium": "", "xxid": "" diff --git a/docs/mibapi/README.md b/docs/mibapi/README.md index 6fde43d..0b2a6cb 100644 --- a/docs/mibapi/README.md +++ b/docs/mibapi/README.md @@ -12,7 +12,7 @@ MIB uses **two completely separate backends**: | Backend | Base URL | Auth | Used for | |---|---|---|---| -| Encrypted API | `https://faisanet.mib.com.mv/faisamobilex_smvc/` | Blowfish + DH session key | Login, key exchange | +| Encrypted API | `https://faisamobilex-smvc-v2.mib.com.mv/index/` | Blowfish + DH session key | Login, key exchange | | WebView host | `https://faisamobilex-wv.mib.com.mv` | Session cookies | Accounts, history, transfers, contacts, cards, financing | --- diff --git a/docs/mibapi/upgradev2.md b/docs/mibapi/upgradev2.md index 5cd5448..315295c 100644 --- a/docs/mibapi/upgradev2.md +++ b/docs/mibapi/upgradev2.md @@ -18,13 +18,13 @@ This document tracks all MIB API calls used by thijooree and their upgrade statu | API Code | Endpoint | Purpose | Used By | Status | |----------|----------|---------|---------|--------| -| `sfunc=r` + `S40` | Key Exchange (Init) | First-time device registration | `MibLoginFlow.kt` | ☐ | -| `sfunc=i` + `S40` | Key Exchange (Login) | Regular login session setup | `MibLoginFlow.kt` | ☐ | -| `sfunc=n` + `C41` | Registration Init | Initialize device registration flow | `MibLoginFlow.kt` | ☐ | -| `sfunc=n` + `C42` | OTP Verification | Verify one-time password after registration | `MibLoginFlow.kt` | ☐ | -| `sfunc=n` + `A41` | Main Login | Submit username/password credentials | `MibLoginFlow.kt` | ☐ | -| `sfunc=n` + `A44` | Get User Salt | Retrieve user salt for password hashing | `MibLoginFlow.kt` | ☐ | -| `sfunc=n` + `P47` | Switch Profile | Activate different user profile | `MibLoginFlow.kt` | ☐ | +| `sfunc=r` + `S40` | Key Exchange (Init) | First-time device registration | `MibLoginFlow.kt` | ✅ | +| `sfunc=i` + `S40` | Key Exchange (Login) | Regular login session setup | `MibLoginFlow.kt` | ✅ | +| `sfunc=n` + `C41` | Registration Init | Initialize device registration flow | `MibLoginFlow.kt` | ✅ | +| `sfunc=n` + `C42` | OTP Verification | Verify one-time password after registration | `MibLoginFlow.kt` | ✅ | +| `sfunc=n` + `A41` | Main Login | Submit username/password credentials | `MibLoginFlow.kt` | ✅ | +| `sfunc=n` + `A44` | Get User Salt | Retrieve user salt for password hashing | `MibLoginFlow.kt` | ✅ | +| `sfunc=n` + `P47` | Switch Profile | Activate different user profile | `MibLoginFlow.kt` | ✅ | --- @@ -132,7 +132,7 @@ This document tracks all MIB API calls used by thijooree and their upgrade statu | Type | URL | |------|-----| -| **Encrypted API** | `https://faisanet.mib.com.mv/faisamobilex_smvc/` | +| **Encrypted API** | `https://faisamobilex-smvc-v2.mib.com.mv/index/` | | **WebView/Data** | `https://faisamobilex-wv.mib.com.mv` | --- @@ -162,20 +162,33 @@ pgf03 = SHA256(clientSalt + SHA256(SHA256(password) + userSalt)) ## Upgrade Checklist -- [ ] Review all 28+ endpoints for v1 compatibility -- [ ] Update authentication flow (encryption/key exchange) -- [ ] Update beneficiary management endpoints -- [ ] Update transfer endpoints (internal, local, account lookup) -- [ ] Update debit card endpoints -- [ ] Update transaction history endpoint -- [ ] Update activity history endpoint -- [ ] Update profile scraping (if API available in v1) -- [ ] Update financing endpoint (if API available in v1) -- [ ] Test session management & keep-alive -- [ ] Verify all error handling & session recovery -- [ ] Test all 8 categories end-to-end +### Core Implementation +- [x] Update encrypted API endpoint URL +- [x] Update User-Agent header +- [x] Add X-Request-ID header +- [x] Verify Blowfish encryption compatibility +- [x] Test device registration flow +- [x] Test regular login flow +- [x] Test OTP verification +- [x] Test profile switching + +### WebView Endpoints (Pending) +- [ ] Test beneficiary management (`/ajaxBeneficiary/*`) +- [ ] Test transfer endpoints (`/ajaxTransfer/*`, `/AjaxAlias/*`) +- [ ] Test debit card endpoints (`/ajaxDebitCard/*`) +- [ ] Test transaction history (`/ajaxAccounts/trxHistory`) +- [ ] Test activity history (`/aProfile/getPagedActivityHistory`) +- [ ] Test user profile scraping (`/personalProfile`) +- [ ] Test financing (`/financing?dashurl=1`) +- [ ] Test session keep-alive (`/aProfile/keepAlive`) + +### Validation +- [ ] Verify all account balances display correctly +- [ ] Verify error handling (419, 505) and auto-recovery +- [ ] Verify all data formats match expectations +- [ ] Full end-to-end user flow test --- -**Started:** 2026-10-22 -**Target Completion:** TBD +**Implementation:** 2026-10-22 ✅ +**WebView Testing:** In progress