9.7 KiB
Aegis Android login-code evidence
Inspection on 9 October 2026, using the published REA 6.1.0 CLI with the
caller-supplied jadx-headless-mcp 0.7.1 provider and OpenJDK 21.0.12.1 on
Linux x64. The case follows the default time-based code in
Aegis Authenticator.
Target
- Official release: v3.4.3, published 6 September 2026.
- Artifact:
aegis-v3.4.3.apk, 6,881,897 bytes. - SHA-256:
fa091c91912c0d56ec3553394fac4158f9a9d178e93bcbb35419601d788cb528. - Package:
com.beemdevelopment.aegis, version code 82. - Reported inventory: 3,077 classes and 1,106 resources.
- Matching source commit:
d6f4e5925a97e4e91593f1542085eae03432a759. - Android provider JAR SHA-256:
6e5eacf500b64292bfb73c49797c1958f6ee44646e43e868039ae7feb573ff75. - Provider source revision:
5844800a486d2248fa949b74c9896285f5b54de2.
The artifact's SHA-256 matches the official GitHub release asset digest and every saved REA record. The APK and provider JAR were downloaded into temporary storage. They are linked from their official releases; neither file is a website asset.
The CLI used REA_JADX_MCP_JAR for its own process. The connected MCP server's
Android provider was initially unavailable; it was not reconfigured. The page
expresses the inspected selections as REA tool requests, using the same operation
parameters as the successful CLI calls. Input paths and result package prefixes
are shortened for display, as noted beside those blocks.
REA findings
Twenty REA operations completed successfully against this artifact. These are the records used for the page's main findings:
| Operation | Finding | Evidence ID |
|---|---|---|
inspect_android_method |
Display calls the timestamp overload for TotpInfo. | ev_c4b51611c987a398359f526dc64866d97a99b146d0ec9177bc1d583a55d64bdc |
trace_android_references |
TotpInfo is one of the three incoming generator callers. | ev_6b5457705a67bd4952f7e17630bcf948538424fae5bc2951c08e921af7448d58 |
inspect_android_method |
Eight-byte big-endian counter, account key and HMAC. | ev_cad4c03faf5b07347cba699d4f8f643c69e5a8f0c85f622fc8cbebe3f834f228 |
inspect_android_method |
Hash-byte selection produces a 31-bit integer. | ev_5797488db16e72a4e9ad559a8f07e355adc1f73b9eb50566cfb46d47d1b6a883 |
inspect_android_method |
Algorithm name is prefixed with Hmac. | ev_bffbfa3924c79823168df7daa01e8a3f62c4914d3fb4b54e5d4e60d21e75110f |
trace_android_references |
Display and copy callers of the base method. | ev_d90e3ed81b0bb6815826e4edf312eadec91b9d20ff06aaff61d38a191403676b |
inspect_android_method |
Default SHA1 algorithm and six digits. | ev_64294487704fa2a9877938017c95163e41c399ba958ea43c5b365118403ae0fe |
inspect_android_method |
Decimal remainder and leading-zero padding. | ev_5d0906d19ea9281fed36309794fd5697b54cac3abfbd17e2f78665e758e0eb60 |
inspect_android_method |
Class discriminator 0 selects the OTP formatting branch. | ev_f0a82295bf6124055b7a12a21533950644267e8e8340038bca9c32db57d8d71f |
inspect_android_package |
Package identity; 3,077 classes. | ev_de07111c281cd76c4f2304f42448b06ef3199268815515d59caa02ea2480eb67 |
inspect_android_class |
Both getOtp overloads and their selection indices. | ev_870577d702741f3023494c1bcb6567381a672a7132a60fd35ea2dd21ab9804c8 |
search_android_classes |
Three matches for the case-sensitive query Totp. | ev_deeb75a09990e253881d0dc1932097abe00f94447d29a64c782fb48c42e9f492 |
inspect_android_method |
Current clock in milliseconds is converted to seconds. | ev_ff4d8be5b4797e6f118d37ed55a2f65c9ceb8df39e8058d2cf36cd5561dc4bfd |
inspect_android_method |
Default period: 30 seconds. | ev_67af69cd39faceec616a9b1b48b03a5ea71b9c94ff2d1263a0a0063029cc1104 |
inspect_android_method |
Time is floored into a block before generation. | ev_f282f536e5690e3e2253903bd979687687cfa5a9a4480758b4cd261da145caaf |
All selected methods returned complete Java representations without a fallback. Signatures are provider display signatures; exact DEX descriptors, source-line locations and instruction offsets are not available from these results. Reference lists are static incoming references, with complete coverage of the engine's reported set; reflection and dynamic loading remain unverified.
Interpretation
TotpInfo.getOtp() obtains Unix time in seconds. Its timestamp overload uses
floor(seconds / period) as the generator's counter. The default constructor
sets the period to 30; the base constructor sets SHA1 and six digits.
These are defaults, not settings imposed on every imported account.
getAlgorithm() constructs HmacSHA1 for that default. The generator encodes the
counter as eight big-endian bytes, calculates the keyed hash, uses the low four
bits of the final hash byte as an offset, and selects a positive 31-bit integer.
The OTP.toString() branch for discriminator 0 reduces it modulo the requested
power of ten and prepends zeroes. The inspected generator passes discriminator 0
into the constructor, connecting that branch to the generated code.
The release exposes generateOTP and getHash under kotlin.ExceptionsKt.
Original-source naming alone would not identify that class in this APK.
The call returned from TotpInfo.getOtp(long) supplies the helper name; REA's
method inspection and reference tracing establish its calculation and callers.
The base OtpInfo.getOtp reference list includes EntryHolder.getOtp and
MainActivity.copyEntryCode. Inspecting EntryHolder.getOtp(int) then shows that
the display calls the timestamp overload for a TotpInfo account, with an
optional period offset. The page uses the unshifted code calculation.
Reconstruction checks
A temporary JVM harness assembled six method bodies directly from saved REA results: the timestamp method, algorithm getter, hash method, generator, output constructor and output formatter. Imports, enclosing classes, fields, exception type and test driver were supplied for the harness. The original APK was not run.
An independently authored Python calculation agreed with those Java methods on 133 inputs. The website's separately authored WebCrypto implementation then agreed with all 133 recorded Java outputs.
The cases include:
- All six RFC 6238 SHA-1 reference vectors at eight digits, plus the corresponding six-digit remainders.
- Every integer second from 0 through 120, checking four complete 30-second blocks and four boundary samples.
- A leading-zero result at Unix time 1,111,111,109:
081804.
The fixed key is the public ASCII test string 12345678901234567890.
At 30 and 59 seconds the result is 287082; at 60 seconds it is 359152.
The diagram labels these as example clock inputs. A code is recomputed for each
block; the checked examples change at their boundaries. Adjacent codes need not
be universally distinct.
The page's “Run reference checks” button tests the browser calculation against all six reference inputs at both digit lengths. Slider updates use a revision number so an earlier asynchronous calculation cannot overwrite a later input. The reference JSON contains public test data, not a captured account key.
Source comparison and attribution
After obtaining the calculation through REA, selected files from the matching release source were read for corroboration:
- HOTP.java: counter encoding, HMAC and byte selection.
- TOTP.java: time-to-counter transformation.
- OTP.java: decimal output and zero padding.
These files confirm the interpretation. The public page's selected decompiled Java comes from the APK evidence. It includes fragments from several methods and line wrapping for display; the paired readable summary is an explanation. The expanded generator panel retains its complete returned body, with formatting changes. Aegis excerpts are credited under the upstream GPL-3.0 license. The diagram, explanatory summary, demo and its WebCrypto implementation are new teaching material; the demo is not recovered original application source.
Scope and maintenance
The claim is a static APK investigation and a checked reconstruction of its
default code calculation. It covers neither Android UI execution nor APK
signature verification, split APK handling, native libraries or vault storage.
The Android provider requires a Linux or macOS host and a full JDK 17 or later,
including jdk.compiler. The shell walkthrough was executed on Linux with
JDK 21.
Raw REA results, provider scratch paths, Java harness classes and the downloaded binaries remain outside the public website. The public page uses generic filenames and the public test key. Update the release identity, selected excerpts, demo, reference data and these notes together when moving to another Aegis version.