Ask your agent
The app shows a changing login code. We want to find what makes it change and reproduce that behavior.
Use REA to inspect aegis-v3.4.3.apk. Find how it generates the six-digit login code, explain why it changes every 30 seconds, and rebuild a small demo where I can change the time.
An example prompt for the downloaded APK, with REA's Android analysis configured. Get the APK and analysis setup ↓
Try the code generator
The app groups time into 30-second blocks. It combines the block number with the account key to generate a code. The same key and block produce the same code.
Move the clock across 60 seconds
- Time secondsOur adjustable example clock
-
30-second blockBlock
floor(59 / 30)
30–59 seconds - Generated codeAccount key + block → six digits
At 59 seconds: 287082. At 60 seconds: 359152. Moving within one block leaves the code unchanged.
Find the code with REA
-
Narrow the APK to three classes
Agent → REAinspect_android_package {"path": "aegis-v3.4.3.apk"} search_android_classes {"path": "aegis-v3.4.3.apk", "query": "Totp"}REA → agent · selected resultsPackage: com.beemdevelopment.aegis Version: 3.4.3 Classes: 3,077 Three matches: otp.TotpInfo ui.views.TotpProgressBar importers.TotpAuthenticatorImporterTotpInfois the calculation candidate; the other two concern the progress bar and imported accounts. TOTP means a time-based one-time password. -
Connect the generator to the app's display
Agent → REAinspect_android_class {"path": "aegis-v3.4.3.apk", "class_name": "com.beemdevelopment.aegis.otp.TotpInfo"} trace_android_references {"path": "aegis-v3.4.3.apk", "class_name": "com.beemdevelopment.aegis.otp.OtpInfo", "method_name": "getOtp"}REA → agent · methods and callersTotpInfo methods: getOtp() · overload 0 getOtp(long) · overload 1 OtpInfo.getOtp callers: ui.views.EntryHolder.getOtp ui.MainActivity.copyEntryCodeREA identifies the timestamp overload and finds the base method's callers. Inspecting
EntryHolder.getOtpthen shows the display callingTotpInfo.getOtp(timestamp).
Requests show a shortened input path. Result class names omit the
common com.beemdevelopment.aegis prefix.
Read the calculation
REA returns the clock conversion, default settings and generating methods. The constructors set a 30-second interval and six digits; the timestamp method turns seconds into a block number.
// TotpInfo defaults and clock
setPeriod(30);
getOtp(System.currentTimeMillis() / 1000);
// OtpInfo default algorithm and digits
this(bArr, "SHA1", 6);
// Block passed to the generator
(long) Math.floor(j / ((double) this._period))
// generateOTP → getHash
byte[] hash = getHash(bArr, str, j);
// getHash: account key + encoded block
Mac mac = Mac.getInstance(str);
mac.init(secretKeySpec);
return mac.doFinal(bArrArray);
// OTP.toString, case 0
this._code % ((int) Math.pow(10.0d, i))
// Keep leading zeroes
while (sb.length() < i) {
sb.insert(0, "0");
}
// Group time into 30-second blocks
seconds = current_time_ms / 1000
block = floor(seconds / 30)
// Generate a number from the key and block
hash = HMAC_SHA1(account_key,
big_endian_8_bytes(block))
number = select_31_bits(hash)
// Format the default six-digit code
code = number % 1_000_000
code = pad_with_zeroes(code, 6)
Time chooses the block. Seconds 30 through 59 all give block 1. At 60 seconds, the block becomes 2.
The key matters too. The generator combines the account key with the block. An account with a different key can show a different code at the same time.
Keep six digits. The remainder after division by 1,000,000 is padded with zeroes when needed, so a code can begin with 0.
Excerpts from several inspected methods, with line wrapping for display. The right panel is an explanatory summary. Aegis code is GPL-3.0.
Inside the generator
The released APK puts generateOTP in
kotlin.ExceptionsKt. REA follows the call from
TotpInfo and returns this body; the original source
calls the helper HOTP.
public static OTP generateOTP(byte[] bArr, String str,
int i, long j)
throws NoSuchAlgorithmException, InvalidKeyException {
byte[] hash = getHash(bArr, str, j);
int i2 = hash[hash.length - 1] & 15;
return new OTP(
(hash[i2 + 3] & 255)
| ((hash[i2] & 127) << 24)
| ((hash[i2 + 1] & 255) << 16)
| ((hash[i2 + 2] & 255) << 8), i, 0);
}
The last hash byte selects a position. Four bytes at that position provide a positive 31-bit number; formatting reduces it to the requested number of digits. The constructor's last argument selects the code-formatting branch introduced by compilation.
Check the reconstruction
We assembled the selected REA-returned Java methods in a small test program. Their output matched an independent reconstruction on 133 test cases, including time-block boundaries and codes beginning with zero.
| Example time | Block | Six-digit code |
|---|---|---|
| 30 seconds | 1 | 287082 |
| 59 seconds | 1 | 287082 |
| 60 seconds | 2 | 359152 |
| 1,111,111,109 seconds | 37,037,036 | 081804 |
The generator also matches the six published SHA-1 reference cases in RFC 6238. Check the browser implementation against them:
The reference cases use eight digits. The check also verifies their six-digit results.
Verification runs extracted Java methods and the new demo. The Android APK was inspected statically.
Inspect the APK yourself
Set up REA on macOS or Linux, then download these two files into the same folder. On Windows, use a Linux environment such as WSL.
Android analysis needs a full JDK 17 or later. Select it with
JAVA_HOME or PATH. This case used JDK
21.
Point REA at the provider file and inspect the APK:
REA_JADX_MCP_JAR="$PWD/jadx-headless-mcp-0.7.1-all.jar" \
npx rea-agents@latest inspect-android-package \
./aegis-v3.4.3.apk --format json --full-output
Your agent can continue through REA's CLI using the prompt above.
For MCP, add REA_JADX_MCP_JAR to the REA server's
environment and reconnect it.
A next question: what happens when an account uses eight digits or a different time interval?
Sources
- Official Aegis 3.4.3 release · Matching source commit · GPL-3.0 license
- RFC 6238 reference cases · Demo test data
Inspected with REA 6.1.0 on 9 October 2026. Decompiled excerpts are credited to Aegis; the diagram, readable summary and browser reconstruction are new teaching material.