An Android profile runs on an ordinary computer and receives a Trustworthy verdict from iphey. The expensive lesson was not to assign phone hardware by hand. One desktop-window constraint remains and is shown openly.
Create a mobile profile with the flag:
The engine selects a coherent mobile identity, including model, chipset, screen and memory. It reports the model in uaData.model, which is where detectors read it. The test suite scores 100 out of 100 and iphey returns Trustworthy; no physical phone is required.
The first version assigned phone hardware from our own model list. That list paired a Pixel 7 with a Redmi chipset. One wrong chipset was enough for iphey to return Unreliable: detectors know real model-and-chipset combinations better than any list maintained by hand.
Three mobile profiles created consecutively on a clean machine:
| Surface | Result |
|---|---|
| Windows-only fonts | none exposed; all thirteen checks passed |
| Video card | different in every profile |
| Reported screen | different in every profile |
| Canvas | different in every profile |
| Logical processor count | eight in every profile, as on the reference phones |
Fonts are the clearest check. If a page saw Calibri or Segoe UI from a profile claiming to be a Pixel, the contradiction would be immediate: those fonts do not ship with Android. We tested thirteen fonts installed only with Windows or Microsoft Office, and the profile exposed none of them.
The mobile profile's layout viewport is wider than its reported screen. The engine changes screen and outerWidth, but the browser still runs in a real desktop window. The profile reports 360×800 while the layout viewport is 500×731. We tested the following approaches:
| Approach | Layout viewport width |
|---|---|
| no adjustment | 500 |
| 412×915 window | 500 |
| 300×600 window | 500 |
| render scale 1.27 | 510 |
| headless mode | 478 |
The constraint is Chrome's minimum desktop window width, roughly 500 CSS pixels. Phones do not use a viewport that wide, so the mismatch cannot be removed while the browser runs in a desktop window. Faking innerWidth independently of layout would not work. The first media query would reveal the real width and create two contradictory values instead of one.
What we could improve: after launch, NimbusX resizes the window to the height reported by the page, and CreepJS no longer highlights the Screen section. The remaining width mismatch is visible in the dashboard: the WIN cell is dimmed and the explanation appears below the table. Hiding it would serve no purpose because a website sees the mismatch before the user does.
Consistency matters more than variety · How fingerprint checks connect profiles