Skip to content

Support direct email/password login (investigation summary and required steps) #2

Description

@BeauGiles

Overview

Currently the integration requires tokens captured via a proxy tool. It would be better UX to support direct email/password login so users don't need a proxy setup.

What we know

The login endpoint is:
POST https://m.iov.changanauto.sg/appgw/intl-app-auth/api/login/email-pass-in

The request body contains:

  • email — RSA encrypted
  • password — RSA encrypted
  • pubKey — the public key used for encryption (sent as a reference)
  • salesCountry — country code e.g. AU

The selectCountry header must NOT be present on this request (unlike all other endpoints).

The problem

The pubKey field sent in the request is a 1024-bit RSA key, but the actual encryption of the credentials produces 344-character output, consistent with a 2048-bit RSA key. This means:

  • The pubKey in the request body is just an identifier/reference sent to the server
  • The actual encryption key used is a different, larger 2048-bit key hardcoded in the app binary
  • Our encryption using the visible pubKey produces 172-character output which the server rejects with APP_1_1_02_001

Investigation

  • The Android APK was inspected — encryption is handled by a native library (libijmDataEncryption.so) via com.ijm.dataencryption.DETool
  • The 2048-bit key is not stored as a plain string in the binary — it appears to be obfuscated within the native library
  • Replaying captured encrypted values from a real app login works correctly, confirming the endpoint and all headers are correct
  • The only missing piece is the actual 2048-bit encryption key

Possible solutions

  1. Extract the key via Frida — hook DETool.encrypt() at runtime on a rooted Android device or emulator to intercept the key material
  2. Reverse engineer the native library — disassemble libijmDataEncryption_arm64.so to find the key
  3. Wait for community contribution — someone with reverse engineering experience may be able to extract the key

Current workaround

Token mode works well. Tokens are automatically refreshed and last ~90 days via the refresh token. When tokens expire a repair notification prompts the user to paste fresh tokens.

The other issue is a user can only be logged in on one device at a time - logging in with your username/password in Home Assistant would likely log you out of your phone if you're already logged in there.

Tokens works fine as a workaround so you can be logged in on both your phone and Home Assistant with the same account.

Metadata

Metadata

Assignees

Labels

enhancementNew feature or request

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions