801 lines
35 KiB
HTML
801 lines
35 KiB
HTML
<!doctype html>
|
||
<html lang="en">
|
||
<head>
|
||
<meta charset="utf-8" />
|
||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||
<title>Aegis APK Reverse Engineering: Login Codes — REA</title>
|
||
<meta
|
||
name="description"
|
||
content="Inspect the Aegis Android APK with REA, recover its six-digit login-code calculation and try a reconstruction with an adjustable clock."
|
||
/>
|
||
<!-- website:sharing:start -->
|
||
<!-- prettier-ignore -->
|
||
<link rel="canonical" href="https://rea.tools/showcase/aegis/" />
|
||
<!-- website:languages:start -->
|
||
<!-- prettier-ignore -->
|
||
<link rel="alternate" hreflang="en" href="https://rea.tools/showcase/aegis/" />
|
||
<!-- prettier-ignore -->
|
||
<link rel="alternate" hreflang="zh-CN" href="https://rea.tools/zh-CN/showcase/aegis/" />
|
||
<!-- prettier-ignore -->
|
||
<link rel="alternate" hreflang="zh-TW" href="https://rea.tools/zh-TW/showcase/aegis/" />
|
||
<!-- prettier-ignore -->
|
||
<link rel="alternate" hreflang="ja" href="https://rea.tools/ja/showcase/aegis/" />
|
||
<!-- prettier-ignore -->
|
||
<link rel="alternate" hreflang="ko" href="https://rea.tools/ko/showcase/aegis/" />
|
||
<!-- prettier-ignore -->
|
||
<link rel="alternate" hreflang="tr" href="https://rea.tools/tr/showcase/aegis/" />
|
||
<!-- prettier-ignore -->
|
||
<link rel="alternate" hreflang="ru" href="https://rea.tools/ru/showcase/aegis/" />
|
||
<!-- prettier-ignore -->
|
||
<link rel="alternate" hreflang="vi" href="https://rea.tools/vi/showcase/aegis/" />
|
||
<!-- prettier-ignore -->
|
||
<link rel="alternate" hreflang="th" href="https://rea.tools/th/showcase/aegis/" />
|
||
<!-- prettier-ignore -->
|
||
<link rel="alternate" hreflang="de" href="https://rea.tools/de/showcase/aegis/" />
|
||
<!-- prettier-ignore -->
|
||
<link rel="alternate" hreflang="es" href="https://rea.tools/es/showcase/aegis/" />
|
||
<!-- prettier-ignore -->
|
||
<link rel="alternate" hreflang="fr" href="https://rea.tools/fr/showcase/aegis/" />
|
||
<!-- prettier-ignore -->
|
||
<link rel="alternate" hreflang="uk" href="https://rea.tools/uk/showcase/aegis/" />
|
||
<!-- prettier-ignore -->
|
||
<link rel="alternate" hreflang="pl" href="https://rea.tools/pl/showcase/aegis/" />
|
||
<!-- prettier-ignore -->
|
||
<link rel="alternate" hreflang="pt-BR" href="https://rea.tools/pt-BR/showcase/aegis/" />
|
||
<!-- prettier-ignore -->
|
||
<link rel="alternate" hreflang="ar" href="https://rea.tools/ar/showcase/aegis/" />
|
||
<!-- prettier-ignore -->
|
||
<link rel="alternate" hreflang="fa" href="https://rea.tools/fa/showcase/aegis/" />
|
||
<!-- prettier-ignore -->
|
||
<link rel="alternate" hreflang="id" href="https://rea.tools/id/showcase/aegis/" />
|
||
<!-- prettier-ignore -->
|
||
<link rel="alternate" hreflang="it" href="https://rea.tools/it/showcase/aegis/" />
|
||
<!-- prettier-ignore -->
|
||
<link rel="alternate" hreflang="x-default" href="https://rea.tools/showcase/aegis/" />
|
||
<!-- website:languages:end -->
|
||
<!-- prettier-ignore -->
|
||
<meta property="og:type" content="website" />
|
||
<!-- prettier-ignore -->
|
||
<meta property="og:site_name" content="REA" />
|
||
<!-- prettier-ignore -->
|
||
<meta property="og:title" content="Aegis APK Reverse Engineering: Login Codes — REA" />
|
||
<!-- prettier-ignore -->
|
||
<meta property="og:description" content="Inspect the Aegis Android APK with REA, recover its six-digit login-code calculation and try a reconstruction with an adjustable clock." />
|
||
<!-- prettier-ignore -->
|
||
<meta property="og:url" content="https://rea.tools/showcase/aegis/" />
|
||
<!-- prettier-ignore -->
|
||
<meta property="og:image" content="https://rea.tools/assets/social-card.png" />
|
||
<!-- prettier-ignore -->
|
||
<meta property="og:image:type" content="image/png" />
|
||
<!-- prettier-ignore -->
|
||
<meta property="og:image:width" content="1200" />
|
||
<!-- prettier-ignore -->
|
||
<meta property="og:image:height" content="630" />
|
||
<!-- prettier-ignore -->
|
||
<meta
|
||
property="og:image:alt"
|
||
content="REA — Find out how software works. Reverse engineering with your coding agent."
|
||
/>
|
||
<!-- prettier-ignore -->
|
||
<meta name="twitter:card" content="summary_large_image" />
|
||
<!-- prettier-ignore -->
|
||
<meta name="twitter:title" content="Aegis APK Reverse Engineering: Login Codes — REA" />
|
||
<!-- prettier-ignore -->
|
||
<meta name="twitter:description" content="Inspect the Aegis Android APK with REA, recover its six-digit login-code calculation and try a reconstruction with an adjustable clock." />
|
||
<!-- prettier-ignore -->
|
||
<meta name="twitter:image" content="https://rea.tools/assets/social-card.png" />
|
||
<!-- prettier-ignore -->
|
||
<meta
|
||
name="twitter:image:alt"
|
||
content="REA — Find out how software works. Reverse engineering with your coding agent."
|
||
/>
|
||
<!-- website:sharing:end -->
|
||
<meta name="theme-color" content="#ffffff" />
|
||
<link rel="icon" href="../../assets/favicon.svg" type="image/svg+xml" />
|
||
<link rel="stylesheet" href="../../assets/styles.css" />
|
||
<script src="../../assets/main.js" defer></script>
|
||
<script type="module" src="../../assets/aegis-demo.js"></script>
|
||
</head>
|
||
<body id="top">
|
||
<a class="skip-link" href="#main">Skip to content</a>
|
||
<!-- website:header:start -->
|
||
<!-- prettier-ignore -->
|
||
<header class="site-header">
|
||
<div class="container header-inner">
|
||
<a class="brand" href="../../" aria-label="REA home"
|
||
><span class="brand-name">REA</span
|
||
><span class="brand-caption" data-i18n-skip>Reverse Engineer Anything</span></a
|
||
>
|
||
<nav class="navigation" aria-label="Main navigation">
|
||
<a href="../../showcase/" aria-current="page">Showcases</a>
|
||
<a href="../../blog/">Blog</a>
|
||
<a href="../../get-started/" class="nav-start">Get started</a>
|
||
<a href="../../guides/">Guides</a>
|
||
<a href="../../faq/">FAQ</a>
|
||
</nav>
|
||
<div class="header-social">
|
||
<details class="language-picker" data-i18n-skip><summary><span aria-hidden="true">文 / A</span> <span>English</span></summary><nav aria-label="English"><a href="../../showcase/aegis/" lang="en" dir="ltr" data-language="en" aria-current="true">English</a><a href="../../zh-CN/showcase/aegis/" lang="zh-CN" dir="ltr" data-language="zh-CN">简体中文</a><a href="../../zh-TW/showcase/aegis/" lang="zh-TW" dir="ltr" data-language="zh-TW">繁體中文</a><a href="../../ja/showcase/aegis/" lang="ja" dir="ltr" data-language="ja">日本語</a><a href="../../ko/showcase/aegis/" lang="ko" dir="ltr" data-language="ko">한국어</a><a href="../../tr/showcase/aegis/" lang="tr" dir="ltr" data-language="tr">Türkçe</a><a href="../../ru/showcase/aegis/" lang="ru" dir="ltr" data-language="ru">Русский</a><a href="../../vi/showcase/aegis/" lang="vi" dir="ltr" data-language="vi">Tiếng Việt</a><a href="../../th/showcase/aegis/" lang="th" dir="ltr" data-language="th">ไทย</a><a href="../../de/showcase/aegis/" lang="de" dir="ltr" data-language="de">Deutsch</a><a href="../../es/showcase/aegis/" lang="es" dir="ltr" data-language="es">Español</a><a href="../../fr/showcase/aegis/" lang="fr" dir="ltr" data-language="fr">Français</a><a href="../../uk/showcase/aegis/" lang="uk" dir="ltr" data-language="uk">Українська</a><a href="../../pl/showcase/aegis/" lang="pl" dir="ltr" data-language="pl">Polski</a><a href="../../pt-BR/showcase/aegis/" lang="pt-BR" dir="ltr" data-language="pt-BR">Português (Brasil)</a><a href="../../ar/showcase/aegis/" lang="ar" dir="rtl" data-language="ar">العربية</a><a href="../../fa/showcase/aegis/" lang="fa" dir="rtl" data-language="fa">فارسی</a><a href="../../id/showcase/aegis/" lang="id" dir="ltr" data-language="id">Bahasa Indonesia</a><a href="../../it/showcase/aegis/" lang="it" dir="ltr" data-language="it">Italiano</a></nav></details>
|
||
<a
|
||
class="nav-github"
|
||
href="https://github.com/morluto/rea"
|
||
aria-label="REA on GitHub"
|
||
title="REA on GitHub"
|
||
>
|
||
<svg
|
||
width="22"
|
||
height="22"
|
||
viewBox="0 0 16 16"
|
||
aria-hidden="true"
|
||
focusable="false"
|
||
>
|
||
<path
|
||
fill="currentColor"
|
||
d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82a7.65 7.65 0 0 1 2-.27c.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.01 8.01 0 0 0 16 8c0-4.42-3.58-8-8-8Z"
|
||
/>
|
||
</svg>
|
||
<span class="nav-github-count" hidden aria-hidden="true"></span>
|
||
</a>
|
||
<a
|
||
class="nav-discord"
|
||
href="https://discord.gg/GkcryMnJDM"
|
||
aria-label="Join REA on Discord"
|
||
title="Join REA on Discord"
|
||
>
|
||
<svg
|
||
width="22"
|
||
height="22"
|
||
viewBox="0 0 24 24"
|
||
aria-hidden="true"
|
||
focusable="false"
|
||
>
|
||
<path
|
||
fill="currentColor"
|
||
d="M20.317 4.3698a19.7913 19.7913 0 0 0-4.8851-1.5152.0741.0741 0 0 0-.0785.0371c-.211.3753-.4447.8648-.6083 1.2495-1.8447-.2762-3.68-.2762-5.4868 0-.1636-.3933-.4058-.8742-.6177-1.2495a.077.077 0 0 0-.0785-.037 19.7363 19.7363 0 0 0-4.8852 1.515.0699.0699 0 0 0-.0321.0277C.5334 9.0458-.319 13.5799.0992 18.0578a.0824.0824 0 0 0 .0312.0561c2.0528 1.5076 4.0413 2.4228 5.9929 3.0294a.0777.0777 0 0 0 .0842-.0276c.4616-.6304.8731-1.2952 1.226-1.9942a.076.076 0 0 0-.0416-.1057c-.6528-.2476-1.2743-.5495-1.8722-.8923a.077.077 0 0 1-.0076-.1277c.1258-.0943.2517-.1923.3718-.2914a.0743.0743 0 0 1 .0776-.0105c3.9278 1.7933 8.18 1.7933 12.0614 0a.0739.0739 0 0 1 .0785.0095c.1202.099.246.1981.3728.2924a.077.077 0 0 1-.0066.1276 12.2986 12.2986 0 0 1-1.873.8914.0766.0766 0 0 0-.0407.1067c.3604.698.7719 1.3628 1.225 1.9932a.076.076 0 0 0 .0842.0286c1.961-.6067 3.9495-1.5219 6.0023-3.0294a.077.077 0 0 0 .0313-.0552c.5004-5.177-.8382-9.6739-3.5485-13.6604a.061.061 0 0 0-.0312-.0286ZM8.02 15.3312c-1.1825 0-2.1569-1.0857-2.1569-2.419 0-1.3332.9555-2.4189 2.157-2.4189 1.2108 0 2.1757 1.0952 2.1568 2.419 0 1.3332-.9555 2.4189-2.1569 2.4189Zm7.9748 0c-1.1825 0-2.1569-1.0857-2.1569-2.419 0-1.3332.9554-2.4189 2.1569-2.4189 1.2108 0 2.1757 1.0952 2.1568 2.419 0 1.3332-.946 2.4189-2.1568 2.4189Z"
|
||
/>
|
||
</svg>
|
||
</a>
|
||
<a
|
||
class="nav-x"
|
||
href="https://x.com/reatools"
|
||
aria-label="Follow REA on X"
|
||
title="Follow REA on X"
|
||
>
|
||
<svg
|
||
width="18"
|
||
height="18"
|
||
viewBox="0 0 24 24"
|
||
aria-hidden="true"
|
||
focusable="false"
|
||
>
|
||
<path
|
||
fill="currentColor"
|
||
d="M18.901 1.153h3.68l-8.04 9.19L24 22.846h-7.406l-5.8-7.584-6.638 7.584H.474l8.6-9.83L0 1.154h7.594l5.243 6.932ZM17.61 20.644h2.039L6.486 3.24H4.298Z"
|
||
/>
|
||
</svg>
|
||
</a>
|
||
</div>
|
||
</div>
|
||
</header>
|
||
<!-- website:header:end -->
|
||
<main id="main" class="container">
|
||
<div class="page-heading">
|
||
<p class="breadcrumb">
|
||
<a href="../../">Home</a> / <a href="../">Showcases</a> / Android
|
||
</p>
|
||
<p class="eyebrow">Case study · Aegis Authenticator</p>
|
||
<h1>How does an authenticator<br />generate a login code?</h1>
|
||
<p class="lede">
|
||
A six-digit code changes every 30 seconds. Use REA to find the
|
||
calculation in an Android APK, then rebuild it with a clock you can
|
||
control.
|
||
</p>
|
||
<p class="page-meta">
|
||
Aegis 3.4.3 · Android · Official release APK · 6.9 MB
|
||
</p>
|
||
<a class="text-link" href="https://github.com/beemdevelopment/Aegis"
|
||
>View Aegis on GitHub</a
|
||
>
|
||
</div>
|
||
|
||
<figure class="workflow-figure case-figure">
|
||
<p class="figure-title">From an APK to a code you can reproduce</p>
|
||
<ol class="flow-steps">
|
||
<li>
|
||
<span class="flow-label">01 · Locate the feature</span
|
||
><strong class="flow-node"
|
||
>3,077 classes → generating methods</strong
|
||
><span class="flow-note"
|
||
>REA searches the package and traces the code used by the display
|
||
and copy actions.</span
|
||
>
|
||
</li>
|
||
<li>
|
||
<span class="flow-label">02 · Read the calculation</span
|
||
><strong class="flow-node">Time + account key → six digits</strong
|
||
><span class="flow-note"
|
||
>REA returns the methods and defaults. The agent explains how they
|
||
fit together.</span
|
||
>
|
||
</li>
|
||
<li>
|
||
<span class="flow-label">03 · Rebuild and check</span
|
||
><strong class="flow-node">Change the clock. Watch the code.</strong
|
||
><span class="flow-note"
|
||
>A new browser demo reproduces the rule and checks it against
|
||
public reference cases.</span
|
||
>
|
||
</li>
|
||
</ol>
|
||
</figure>
|
||
|
||
<div class="article-layout">
|
||
<nav class="contents" aria-label="On this page">
|
||
<p>In this case study</p>
|
||
<ul>
|
||
<li><a href="#ask">Ask your agent</a></li>
|
||
<li><a href="#demo">Try the code generator</a></li>
|
||
<li><a href="#find">Find the code with REA</a></li>
|
||
<li><a href="#calculation">Read the calculation</a></li>
|
||
<li><a href="#verify">Check the reconstruction</a></li>
|
||
<li><a href="#try">Inspect the APK yourself</a></li>
|
||
</ul>
|
||
</nav>
|
||
<article class="article" aria-label="Aegis APK case study">
|
||
<section class="article-section" id="ask">
|
||
<h2>Ask your agent</h2>
|
||
<p>
|
||
The app shows a changing login code. We want to find
|
||
<strong>what makes it change</strong> and reproduce that behavior.
|
||
</p>
|
||
<div class="agent-terminal">
|
||
<div class="terminal-header">
|
||
<span class="terminal-title"
|
||
><span class="terminal-dots" aria-hidden="true"
|
||
><i></i><i></i><i></i></span
|
||
>Your coding agent</span
|
||
><button
|
||
class="copy-button"
|
||
type="button"
|
||
data-copy="aegis-prompt"
|
||
aria-label="Copy Aegis example prompt"
|
||
>
|
||
Copy
|
||
</button>
|
||
</div>
|
||
<p class="terminal-prompt">
|
||
<span class="prompt-symbol" aria-hidden="true">›</span
|
||
><span id="aegis-prompt"
|
||
>Use REA to inspect aegis-v3.4.<span translate="no"
|
||
>3.apk</span
|
||
>. 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.</span
|
||
><span class="terminal-cursor" aria-hidden="true"></span>
|
||
</p>
|
||
</div>
|
||
<p class="caption">
|
||
An example prompt for the downloaded APK, with REA's Android
|
||
analysis configured.
|
||
<a href="#try">Get the APK and analysis setup ↓</a>
|
||
</p>
|
||
</section>
|
||
|
||
<section class="article-section" id="demo">
|
||
<h2>Try the code generator</h2>
|
||
<p>
|
||
The app groups time into
|
||
<mark class="prose-highlight">30-second blocks.</mark> It combines
|
||
the block number with the account key to generate a code. The same
|
||
key and block produce the same code.
|
||
</p>
|
||
<figure class="workflow-figure aegis-demo" data-aegis-demo>
|
||
<p class="figure-title">Move the clock across 60 seconds</p>
|
||
<ol class="flow-steps aegis-calculation">
|
||
<li>
|
||
<span class="flow-label">Time</span
|
||
><strong class="flow-node"
|
||
><output data-aegis-seconds>59</output> seconds</strong
|
||
><span class="flow-note">Our adjustable example clock</span>
|
||
</li>
|
||
<li>
|
||
<span class="flow-label">30-second block</span
|
||
><strong class="flow-node"
|
||
>Block <output data-aegis-block>1</output></strong
|
||
><span class="flow-note"
|
||
><code data-aegis-division>floor(59 / 30)</code><br /><span
|
||
data-aegis-window
|
||
>30–59 seconds</span
|
||
></span
|
||
>
|
||
</li>
|
||
<li>
|
||
<span class="flow-label">Generated code</span
|
||
><strong class="flow-node aegis-code"
|
||
><output
|
||
data-aegis-code
|
||
aria-live="polite"
|
||
aria-atomic="true"
|
||
>287082</output
|
||
></strong
|
||
><span class="flow-note"
|
||
>Account key + block → six digits</span
|
||
>
|
||
</li>
|
||
</ol>
|
||
<div class="aegis-clock-controls">
|
||
<label for="aegis-clock">Example time, in seconds</label>
|
||
<input
|
||
id="aegis-clock"
|
||
type="range"
|
||
min="0"
|
||
max="120"
|
||
step="1"
|
||
value="59"
|
||
disabled
|
||
/>
|
||
<div class="aegis-clock-scale" aria-hidden="true">
|
||
<span>0</span><span>30</span><span>60</span><span>90</span
|
||
><span>120</span>
|
||
</div>
|
||
<div class="actions">
|
||
<button
|
||
class="button secondary"
|
||
type="button"
|
||
data-aegis-time="59"
|
||
disabled
|
||
>
|
||
59 seconds</button
|
||
><button
|
||
class="button secondary"
|
||
type="button"
|
||
data-aegis-time="60"
|
||
disabled
|
||
>
|
||
60 seconds
|
||
</button>
|
||
</div>
|
||
<p class="caption">
|
||
At 59 seconds: <strong>287082.</strong> At 60 seconds:
|
||
<strong>359152.</strong> Moving within one block leaves the
|
||
code unchanged.
|
||
</p>
|
||
<p class="caption" data-aegis-status role="status"></p>
|
||
</div>
|
||
<figcaption>
|
||
The key is fixed, public
|
||
<a href="https://www.rfc-editor.org/rfc/rfc6238.html#appendix-B"
|
||
>RFC 6238 test data</a
|
||
>. The demo implements the calculation recovered from the APK.
|
||
</figcaption>
|
||
<noscript
|
||
><p class="caption">
|
||
The diagram shows the result at 59 seconds. Enable JavaScript
|
||
to change the clock.
|
||
</p></noscript
|
||
>
|
||
</figure>
|
||
</section>
|
||
|
||
<section class="article-section" id="find">
|
||
<h2>Find the code with REA</h2>
|
||
<ol class="rea-queries">
|
||
<li>
|
||
<h4>Narrow the APK to three classes</h4>
|
||
<div class="rea-query-pair">
|
||
<div class="code-block">
|
||
<div class="code-header"><span>Agent → REA</span></div>
|
||
<pre><code>inspect_android_package
|
||
{"path": "aegis-v3.4.3.apk"}
|
||
|
||
search_android_classes
|
||
{"path": "aegis-v3.4.3.apk",
|
||
"query": "Totp"}</code></pre>
|
||
</div>
|
||
<div class="code-block">
|
||
<div class="code-header">
|
||
<span>REA → agent · selected results</span>
|
||
</div>
|
||
<pre><code>Package: com.beemdevelopment.aegis
|
||
Version: 3.4.3
|
||
Classes: 3,077
|
||
|
||
Three matches:
|
||
otp.TotpInfo
|
||
ui.views.TotpProgressBar
|
||
importers.TotpAuthenticatorImporter</code></pre>
|
||
</div>
|
||
</div>
|
||
<p>
|
||
<code>TotpInfo</code> is the calculation candidate; the other
|
||
two concern the progress bar and imported accounts. TOTP means
|
||
a time-based one-time password.
|
||
</p>
|
||
</li>
|
||
<li>
|
||
<h4>Connect the generator to the app's display</h4>
|
||
<div class="rea-query-pair">
|
||
<div class="code-block">
|
||
<div class="code-header"><span>Agent → REA</span></div>
|
||
<pre><code>inspect_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"}</code></pre>
|
||
</div>
|
||
<div class="code-block">
|
||
<div class="code-header">
|
||
<span>REA → agent · methods and callers</span>
|
||
</div>
|
||
<pre><code>TotpInfo methods:
|
||
getOtp() · overload 0
|
||
getOtp(long) · overload 1
|
||
|
||
OtpInfo.getOtp callers:
|
||
ui.views.EntryHolder.getOtp
|
||
ui.MainActivity.copyEntryCode</code></pre>
|
||
</div>
|
||
</div>
|
||
<p>
|
||
REA identifies the timestamp overload and finds the base
|
||
method's callers. Inspecting
|
||
<code>EntryHolder.getOtp</code> then shows the display calling
|
||
<code>TotpInfo.getOtp(timestamp)</code>.
|
||
</p>
|
||
</li>
|
||
</ol>
|
||
<p class="caption">
|
||
Requests show a shortened input path. Result class names omit the
|
||
common <code>com.beemdevelopment.aegis</code> prefix.
|
||
</p>
|
||
</section>
|
||
|
||
<section class="article-section" id="calculation">
|
||
<h2>Read the calculation</h2>
|
||
<p>
|
||
REA returns
|
||
<strong
|
||
>the clock conversion, default settings and generating
|
||
methods.</strong
|
||
>
|
||
The constructors set a 30-second interval and six digits; the
|
||
timestamp method turns seconds into a block number.
|
||
</p>
|
||
<div class="step-comparison" data-step-comparison>
|
||
<div
|
||
class="step-selector aegis-step-selector"
|
||
role="group"
|
||
aria-label="Follow the login-code calculation"
|
||
>
|
||
<button
|
||
type="button"
|
||
data-select-step="1"
|
||
aria-pressed="true"
|
||
aria-controls="aegis-java aegis-summary"
|
||
>
|
||
<span>01</span> Time block
|
||
</button>
|
||
<button
|
||
type="button"
|
||
data-select-step="2"
|
||
aria-pressed="false"
|
||
aria-controls="aegis-java aegis-summary"
|
||
>
|
||
<span>02</span> Key + block
|
||
</button>
|
||
<button
|
||
type="button"
|
||
data-select-step="3"
|
||
aria-pressed="false"
|
||
aria-controls="aegis-java aegis-summary"
|
||
>
|
||
<span>03</span> Six digits
|
||
</button>
|
||
</div>
|
||
<div class="code-comparison">
|
||
<div class="code-block">
|
||
<div class="code-header">
|
||
<span>REA · selected decompiled Java</span>
|
||
</div>
|
||
<pre><code id="aegis-java"><span class="code-step is-active" data-step="1">// 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))</span>
|
||
|
||
<span class="code-step" data-step="2">// 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);</span>
|
||
|
||
<span class="code-step" data-step="3">// OTP.toString, case 0
|
||
this._code % ((int) Math.pow(10.0d, i))
|
||
|
||
// Keep leading zeroes
|
||
while (sb.length() < i) {
|
||
sb.insert(0, "0");
|
||
}</span></code></pre>
|
||
</div>
|
||
<div class="code-block">
|
||
<div class="code-header">
|
||
<span>Readable summary · agent's interpretation</span>
|
||
</div>
|
||
<pre><code id="aegis-summary"><span class="code-step is-active" data-step="1">// Group time into 30-second blocks
|
||
seconds = current_time_ms / 1000
|
||
block = floor(seconds / 30)</span>
|
||
|
||
<span class="code-step" data-step="2">// Generate a number from the key and block
|
||
hash = HMAC_SHA1(account_key,
|
||
big_endian_8_bytes(block))
|
||
number = select_31_bits(hash)</span>
|
||
|
||
<span class="code-step" data-step="3">// Format the default six-digit code
|
||
code = number % 1_000_000
|
||
code = pad_with_zeroes(code, 6)</span></code></pre>
|
||
</div>
|
||
</div>
|
||
<div class="step-detail" data-step-note="1">
|
||
<p>
|
||
<strong>Time chooses the block.</strong> Seconds 30 through 59
|
||
all give block 1. At 60 seconds, the block becomes 2.
|
||
</p>
|
||
</div>
|
||
<div class="step-detail" data-step-note="2">
|
||
<p>
|
||
<strong>The key matters too.</strong> The generator combines
|
||
the account key with the block. An account with a different
|
||
key can show a different code at the same time.
|
||
</p>
|
||
</div>
|
||
<div class="step-detail" data-step-note="3">
|
||
<p>
|
||
<strong>Keep six digits.</strong> The remainder after division
|
||
by 1,000,000 is padded with zeroes when needed, so a code can
|
||
begin with 0.
|
||
</p>
|
||
</div>
|
||
</div>
|
||
<p class="caption">
|
||
Excerpts from several inspected methods, with line wrapping for
|
||
display. The right panel is an explanatory summary.
|
||
<a
|
||
href="https://github.com/beemdevelopment/Aegis/blob/d6f4e5925a97e4e91593f1542085eae03432a759/LICENSE"
|
||
>Aegis code is GPL-3.0.</a
|
||
>
|
||
</p>
|
||
<details class="evidence-details">
|
||
<summary>Inside the generator</summary>
|
||
<p>
|
||
The released APK puts <code>generateOTP</code> in
|
||
<code>kotlin.ExceptionsKt</code>. REA follows the call from
|
||
<code>TotpInfo</code> and returns this body; the original source
|
||
calls the helper <code>HOTP</code>.
|
||
</p>
|
||
<div class="code-block">
|
||
<div class="code-header">
|
||
<span>REA · generateOTP, complete body</span>
|
||
</div>
|
||
<pre><code>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);
|
||
}</code></pre>
|
||
</div>
|
||
<p>
|
||
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.
|
||
</p>
|
||
<p>
|
||
<a
|
||
href="https://github.com/beemdevelopment/Aegis/blob/d6f4e5925a97e4e91593f1542085eae03432a759/app/src/main/java/com/beemdevelopment/aegis/crypto/otp/HOTP.java"
|
||
>Compare with the matching release source</a
|
||
>.
|
||
</p>
|
||
</details>
|
||
</section>
|
||
|
||
<section class="article-section" id="verify">
|
||
<h2>Check the reconstruction</h2>
|
||
<p>
|
||
We assembled the selected REA-returned Java methods in a small
|
||
test program. Their output matched an independent reconstruction
|
||
on <strong>133 test cases</strong>, including time-block
|
||
boundaries and codes beginning with zero.
|
||
</p>
|
||
<div class="evidence-table-wrap">
|
||
<table class="evidence-table">
|
||
<thead>
|
||
<tr>
|
||
<th>Example time</th>
|
||
<th>Block</th>
|
||
<th>Six-digit code</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<tr>
|
||
<td>30 seconds</td>
|
||
<td>1</td>
|
||
<td><code>287082</code></td>
|
||
</tr>
|
||
<tr>
|
||
<td>59 seconds</td>
|
||
<td>1</td>
|
||
<td><code>287082</code></td>
|
||
</tr>
|
||
<tr>
|
||
<td>60 seconds</td>
|
||
<td>2</td>
|
||
<td><code>359152</code></td>
|
||
</tr>
|
||
<tr>
|
||
<td>1,111,111,109 seconds</td>
|
||
<td>37,037,036</td>
|
||
<td><code>081804</code></td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
<p>
|
||
The generator also matches the six published SHA-1 reference cases
|
||
in
|
||
<a href="https://www.rfc-editor.org/rfc/rfc6238.html#appendix-B"
|
||
>RFC 6238</a
|
||
>. Check the browser implementation against them:
|
||
</p>
|
||
<div class="actions">
|
||
<button
|
||
class="button secondary"
|
||
type="button"
|
||
data-aegis-check
|
||
disabled
|
||
>
|
||
Run reference checks</button
|
||
><a class="text-link" href="../../assets/aegis-otp.js"
|
||
>Read the demo's calculation</a
|
||
>
|
||
</div>
|
||
<p
|
||
class="caption"
|
||
data-aegis-check-result
|
||
role="status"
|
||
aria-live="polite"
|
||
>
|
||
The reference cases use eight digits. The check also verifies
|
||
their six-digit results.
|
||
</p>
|
||
<p class="caption">
|
||
Verification runs extracted Java methods and the new demo. The
|
||
Android APK was inspected statically.
|
||
</p>
|
||
</section>
|
||
|
||
<section class="article-section" id="try">
|
||
<h2>Inspect the APK yourself</h2>
|
||
<p>
|
||
<a href="../../get-started/">Set up REA</a> on macOS or Linux,
|
||
then download these two files into the same folder. On Windows,
|
||
use a Linux environment such as WSL.
|
||
</p>
|
||
<p>
|
||
Android analysis needs a full JDK 17 or later. Select it with
|
||
<code>JAVA_HOME</code> or <code>PATH</code>. This case used JDK
|
||
21.
|
||
</p>
|
||
<div class="actions">
|
||
<a
|
||
class="button"
|
||
href="https://github.com/beemdevelopment/Aegis/releases/download/v3.4.3/aegis-v3.4.3.apk"
|
||
>Download Aegis APK</a
|
||
><a
|
||
class="text-link"
|
||
href="https://github.com/1013503897/jadx-headless-mcp/releases/download/v0.7.1/jadx-headless-mcp-0.7.1-all.jar"
|
||
>Download Android analysis provider</a
|
||
>
|
||
</div>
|
||
<p>Point REA at the provider file and inspect the APK:</p>
|
||
<div class="code-block">
|
||
<div class="code-header">
|
||
<span>macOS / Linux</span
|
||
><button
|
||
class="copy-button"
|
||
type="button"
|
||
data-copy="aegis-inspect-command"
|
||
aria-label="Copy APK inspection command"
|
||
>
|
||
Copy
|
||
</button>
|
||
</div>
|
||
<pre><code id="aegis-inspect-command">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</code></pre>
|
||
</div>
|
||
<p>
|
||
Your agent can continue through REA's CLI using the prompt above.
|
||
For MCP, add <code>REA_JADX_MCP_JAR</code> to the REA server's
|
||
environment and reconnect it.
|
||
</p>
|
||
<p>
|
||
A next question:
|
||
<strong
|
||
>what happens when an account uses eight digits or a different
|
||
time interval?</strong
|
||
>
|
||
</p>
|
||
</section>
|
||
|
||
<section class="article-section" id="sources">
|
||
<h2>Sources</h2>
|
||
<ul class="compact-list">
|
||
<li>
|
||
<a
|
||
href="https://github.com/beemdevelopment/Aegis/releases/tag/v3.4.3"
|
||
>Official Aegis 3.4.3 release</a
|
||
>
|
||
·
|
||
<a
|
||
href="https://github.com/beemdevelopment/Aegis/tree/d6f4e5925a97e4e91593f1542085eae03432a759"
|
||
>Matching source commit</a
|
||
>
|
||
·
|
||
<a
|
||
href="https://github.com/beemdevelopment/Aegis/blob/d6f4e5925a97e4e91593f1542085eae03432a759/LICENSE"
|
||
>GPL-3.0 license</a
|
||
>
|
||
</li>
|
||
<li>
|
||
<a href="https://www.rfc-editor.org/rfc/rfc6238.html#appendix-B"
|
||
>RFC 6238 reference cases</a
|
||
>
|
||
· <a href="test-vectors.json">Demo test data</a>
|
||
</li>
|
||
</ul>
|
||
<p class="caption">
|
||
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.
|
||
</p>
|
||
</section>
|
||
</article>
|
||
</div>
|
||
</main>
|
||
<!-- website:footer:start -->
|
||
<!-- prettier-ignore -->
|
||
<footer class="site-footer">
|
||
<div class="container footer-inner">
|
||
<p>REA · Reverse Engineer Anything</p>
|
||
<div class="footer-links">
|
||
<a href="https://github.com/morluto/rea">Source</a
|
||
><a href="https://github.com/morluto/rea/blob/main/LICENSE">MIT license</a
|
||
><a href="https://discord.gg/GkcryMnJDM">Join the community</a
|
||
><a href="https://x.com/reatools">Follow us on X</a>
|
||
</div>
|
||
</div>
|
||
</footer>
|
||
<p class="sr-only" id="copy-status" role="status" aria-live="polite"></p>
|
||
<a class="back-to-top" href="#top" aria-label="Back to top">
|
||
<span aria-hidden="true">↑</span> Top
|
||
</a>
|
||
<!-- website:footer:end -->
|
||
</body>
|
||
</html>
|