Android / Caso práctico resuelto / 18 min de lectura

Aegis: ¿por qué cambia el código a los 60 segundos?

Un autenticador parece limitarse a seis dígitos y un temporizador. Sigue la investigación documentada de Aegis con REA y prueba después una pequeña versión con un reloj que tú controlas.

En esta página
El objetivo

Recuperar el cálculo de un código basado en el tiempo, reproducirlo en el navegador y comprobar el límite entre dos intervalos de 30 segundos.

Antes de empezar

La demostración funciona de inmediato. Para repetir la inspección del APK, necesitas REA, Aegis v3.4.3, un JDK 17+ completo y el proveedor jadx descrito en nuestra guía de Android.

01. Pasar de 59 a 60 segundos

Pulsa los dos botones de tiempo de abajo. Con la clave pública de prueba fija, 59 segundos produce 287082; 60 segundos produce 359152. Vuelve a 30 segundos: reaparece el primer código porque 30 y 59 pertenecen al mismo intervalo temporal.

El código de 30 segundos LABORATORIO INTERACTIVO

CLAVE PÚBLICA DE PRUEBA · SHA-1 · 6 DÍGITOS

287082

Tiempo Unix 59s Contador 1

0s30s60s90s120s

59 ÷ 30 → contador 1. A los 60 segundos, el contador pasa a 2.

Implementación didáctica nueva que utiliza la clave pública de prueba del RFC 6238. Sin secretos de cuentas. Sin llamadas a REA desde tu navegador.

Estos números son segundos transcurridos desde el inicio de la época Unix, no los segundos que muestra tu reloj. La demostración implementa TOTP estándar con la clave ASCII pública 12345678901234567890. No lee una bóveda de Aegis ni utiliza un secreto de cuenta.

02. Encontrar el método basado en el tiempo en el APK

El informe oficial de REA inspeccionó Aegis v3.4.3 con REA 6.1.0. Para seguir sus pasos, obtén esa versión, registra su hash y busca la clase TOTP. Los comandos siguientes utilizan REA 6.4.0.

Terminal
npx -y [email protected] inspect-android-package "/absolute/path/aegis-v3.4.3.apk" --json
npx -y [email protected] search-android-classes "/absolute/path/aegis-v3.4.3.apk" Totp --json

Usa el nombre exacto de la clase devuelta para inspeccionar sus miembros. La sobrecarga de getOtp que acepta una marca de tiempo resulta útil porque permite proporcionar el tiempo directamente. Selecciónala en el inventario en vez de suponer que el primer método con ese nombre es el correcto.

Instrucción de investigación
Usa REA para inspeccionar la clase TotpInfo en /absolute/path/aegis-v3.4.3.apk. Selecciona la sobrecarga getOtp que acepta una marca de tiempo. Sigue sus llamadas a través de la codificación del contador, HMAC, el truncamiento y el formato decimal. Recupera el período, el hash y la cantidad de dígitos predeterminados. Cita cada método inspeccionado y distingue los valores predeterminados de la configuración de cada cuenta. No ejecutes el APK.

03. Recuperar el cálculo completo

Encontrar una división entre 30 es solo el comienzo. El informe del proyecto original conecta cinco etapas: convertir el tiempo en un contador mediante redondeo hacia abajo; codificarlo en ocho bytes big-endian; calcular HMAC con la clave; seleccionar un valor positivo de 31 bits del hash; reducirlo a seis dígitos y conservar los ceros iniciales.

Tiempo→Contador→HMAC→6 dígitos

Sigue las llamadas a métodos devueltas en lugar de basarte en nombres de código conocidos. En la versión inspeccionada, la optimización situó las funciones auxiliares del generador en kotlin.ExceptionsKt. El informe también distingue los valores predeterminados de SHA-1, seis dígitos y 30 segundos de la configuración específica de cada cuenta.

04. Reconstruir la regla y probar los límites

Implementa de forma independiente el comportamiento recuperado y utiliza después vectores públicos de referencia. Prueba los instantes inmediatamente anteriores y posteriores a un límite temporal, un resultado con cero inicial y las salidas de seis y ocho dígitos. No existe garantía matemática de que dos intervalos contiguos tengan códigos diferentes, aunque en este ejemplo sí ocurre.

Instrucción de reconstrucción
Escribe una pequeña implementación TOTP independiente para este comportamiento recuperado. Usa solo las claves públicas de prueba del RFC 6238. Verifica las seis marcas de tiempo de referencia SHA-1 con ocho dígitos y sus restos de seis dígitos. Prueba los límites 29/30 y 59/60, y conserva los ceros iniciales. Explica cualquier diferencia con el método inspeccionado; no afirmes haber reconstruido la bóveda ni la aplicación Android.
Tiempo UnixContadorResultado de 6 dígitosQué comprueba
290755224Final del primer intervalo
301287082Límite cruzado
591287082Mismo intervalo
602359152Siguiente contador
111111110937037036081804Cero inicial conservado

05. Entender qué significa «133 comprobaciones»

El proyecto original documenta la coincidencia de 133 entradas entre un banco de pruebas JVM ensamblado a partir de métodos descompilados seleccionados y reconstrucciones independientes. No ejecutó el APK original. Esto respalda el cálculo seleccionado, no la equivalencia de toda la aplicación.

Para este sitio, escribimos una demostración WebCrypto independiente y comprobamos los seis vectores SHA-1 publicados con dos cantidades de dígitos, además de cada segundo entero de 0 a 120, frente a una implementación HMAC separada en Node. No repetimos la investigación del APK original ni su banco de pruebas Java.

Fuentes: Informe de pruebas de Aegis de REA · Vectores de prueba del RFC 6238. Demostración y explicación de autoría independiente. Aquí no se redistribuye el código fuente de la aplicación Aegis.

Siguiente investigación¿Cómo copia Notion el texto enriquecido? →

¿Acabas de conocer la herramienta? ¿Qué es REA? · Cómo revisamos nuestras guías