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
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 empezarLa 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.
CLAVE PÚBLICA DE PRUEBA · SHA-1 · 6 DÍGITOS
Tiempo Unix 59s Contador 1
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.
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 --jsonUsa 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.
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.
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.
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 Unix | Contador | Resultado de 6 dígitos | Qué comprueba |
|---|---|---|---|
| 29 | 0 | 755224 | Final del primer intervalo |
| 30 | 1 | 287082 | Límite cruzado |
| 59 | 1 | 287082 | Mismo intervalo |
| 60 | 2 | 359152 | Siguiente contador |
| 1111111109 | 37037036 | 081804 | Cero 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.
¿Acabas de conocer la herramienta? ¿Qué es REA? · Cómo revisamos nuestras guías