Skip to Content
Nueva versión 12 disponible 🎉
ObfuscatorCifrado de cadenasAlgoritmos estándar

Algoritmos estándar

Babel Obfuscator incluye tres algoritmos integrados de cifrado de cadenas: XOR, HASH y STREAM. Los tres son autónomos (descifran sin ninguna entrada externa), de modo que elegir entre ellos supone buscar un equilibrio entre el tiempo de carga, el tamaño de la salida y lo difícil que resulta recuperar las cadenas. En esta página se describe cada algoritmo y cómo activarlo; la tabla comparativa del final resume las diferencias.

Algoritmo XOR

El algoritmo XOR que Babel Obfuscator usa para cifrar cadenas es un algoritmo sencillo, que aplica la operación XOR entre los caracteres de la cadena en línea y una clave entera aleatoria. Este método tiene la ventaja de permitir un descifrado más rápido y un tiempo de carga menor que otros algoritmos de cifrado.

Línea de comandos

Para configurar el algoritmo de cifrado XOR en su aplicación con Babel Obfuscator desde la línea de comandos, use este sencillo comando:

babel myapp.exe --string xor

Este comando indica a Babel que aplique el cifrado XOR a las cadenas en línea del ejecutable de su aplicación, y aprovecha la sencillez y la rapidez del algoritmo XOR para ofuscar las cadenas de forma segura.

Tarea Babel de MSBuild

Configurar el algoritmo XOR para el cifrado de cadenas en su proyecto con la tarea Babel de MSBuild es sencillo. Basta con añadir a su archivo de proyecto de MSBuild un grupo de propiedades y una tarea Babel con la configuración específica del método de cifrado XOR:

<PropertyGroup> <StringEncryption>xor</StringEncryption> </PropertyGroup> <Babel StringEncryption="$(StringEncryption)" />

Con esta configuración, Babel Obfuscator aplica el algoritmo de cifrado XOR a las cadenas de su proyecto, lo que mejora su seguridad y las hace más resistentes a la manipulación y a los intentos de ingeniería inversa.

Algoritmo HASH

El algoritmo HASH de Babel Obfuscator se basa en tablas hash a las que se accede mediante claves enteras. Este algoritmo comprime y cifra los datos de las cadenas, lo que puede ayudar a reducir el tamaño total que esos datos ocupan en el archivo. Sin embargo, como los datos comprimidos de las cadenas deben descifrarse en tiempo de ejecución, puede afectar al tiempo de carga de la aplicación. En comparación con el algoritmo XOR, que aplica la operación XOR entre los caracteres de la cadena en línea y una clave entera aleatoria, el algoritmo HASH ofrece mejor protección frente a los ataques de descifrado de cadenas, pero a costa de un tiempo de carga mayor.

Línea de comandos

Para configurar el cifrado HASH con Babel Obfuscator desde la CLI, use este comando:

babel myapp.exe --string hash

Tarea Babel de MSBuild

Para activar el cifrado HASH con la tarea de MSBuild de Babel, establezca la propiedad StringEncryption como sigue:

<PropertyGroup> <StringEncryption>hash</StringEncryption> </PropertyGroup> <Babel StringEncryption="$(StringEncryption)" />

Con esta integración del algoritmo HASH, las cadenas de su proyecto quedan adecuadamente protegidas durante el proceso de compilación.

Algoritmo STREAM Ultimate

El algoritmo STREAM es la opción moderna y autenticada de cifrado de cadenas de Babel Obfuscator. Cifra cada cadena por separado con un algoritmo de cifrado robusto y estándar del sector, y verifica una etiqueta de autenticación antes de devolverla. Esto da a STREAM cuatro propiedades que los algoritmos anteriores no tienen:

  • Descifrado diferido, cadena a cadena. Una cadena solo se descifra la primera vez que se usa realmente, y el resultado se guarda en caché. A diferencia de HASH, STREAM nunca descifra todo el conjunto por adelantado, de modo que un volcado de memoria solo expone las pocas cadenas que la aplicación ya ha usado: no existe ningún momento en el que todas las cadenas estén en memoria en texto sin cifrar.
  • Integridad y aleatorización por cadena. La etiqueta de autenticación detecta cualquier manipulación de los datos cifrados, y dos cadenas idénticas se cifran en bytes distintos, lo que anula el análisis de frecuencia y de igualdad al que se presta un esquema XOR sencillo.
  • Una clave que nunca se almacena en línea. La clave no se guarda como literal junto a la llamada de descifrado, de modo que un desofuscador automático tiene que ejecutar el código real para recuperar una cadena, en lugar de limitarse a leer una clave situada junto a la llamada.
  • Descifrado vinculado al contexto de llamada de su código. Ejecutar el descifrador no basta: solo devuelve una cadena a un llamador que se ejecuta dentro del propio ensamblado protegido (o dentro del entorno de ejecución de .NET, para que LINQ/PLINQ y las rutas asíncronas sigan funcionando). Queda así bloqueada la forma habitual en que un desofuscador automático vuelca de una vez, con un solo comando, todas las cadenas cifradas: vincular un delegado directamente al descifrador e invocarlo por lotes desde su propio ensamblado auxiliar. Esto no hace imposible recuperar las cadenas con un análisis dinámico completo, pero elimina la vía barata de extracción masiva y obliga al atacante a ejecutar el código real de su aplicación.

El descifrador está escrito íntegramente en código administrado, sin dependencia alguna del proveedor criptográfico de la plataforma. Por eso STREAM se ejecuta sin cambios desde .NET Framework 4.x (y 2.0) hasta .NET 10, en Mono/Xamarin y, como no usa Reflection.Emit, en aplicaciones NativeAOT y recortadas. Tampoco le afecta el problema de arranque relacionado con FIPS que pueden sufrir los algoritmos basados en la plataforma.

STREAM es autónomo: igual que XOR y HASH, descifra sin ninguna entrada externa. Al ser un esquema exclusivamente local, no puede hacer imposible la recuperación de las cadenas con un análisis dinámico completo (ningún esquema autónomo puede), pero eleva el coste de la extracción automática y de la ingeniería inversa manual muy por encima del de XOR y HASH.

Compatibilidad con plataformas y frameworks

Como el descifrador es totalmente administrado y no usa Reflection.Emit, código dinámico, recorrido de la pila ni el proveedor criptográfico de la plataforma, STREAM se ha verificado en toda la gama de .NET y en dispositivos móviles:

  • De .NET Framework 2.0 / 4.x a .NET 10, .NET Core y Mono / Xamarin.
  • Aplicaciones recortadas (ILLink) y NativeAOT: el descifrador inyectado y su tabla de cadenas incrustada sobreviven al enlazado, y el código se compila de forma anticipada, sin JIT.
  • Android e iOS: verificado de extremo a extremo con aplicaciones reales ofuscadas en el emulador de Android y en el simulador de iOS, incluidas las compilaciones Release totalmente recortadas. Las cadenas se descifran en tiempo de ejecución y no queda texto sin cifrar en el ensamblado empaquetado. .NET MAUI se basa en estos mismos entornos de ejecución (net*-android / net*-ios), así que la compatibilidad es la misma. El AOT completo en dispositivos iOS queda cubierto por la compatibilidad con NativeAOT indicada más arriba.

En dispositivos móviles, aplique STREAM en una pasada que solo cifre las cadenas, de modo que los nombres de tipos y miembros queden intactos para la capa de interoperabilidad con Java / Objective-C:

babel MyApp.dll --stringencryption stream --notypes --nomethods --nofields --noproperties --noevents --noparameters --novirtualmembers

Cuando Babel se ejecuta como un paso de MSBuild dentro de una compilación de .NET para Android / iOS / MAUI, insértelo después de que se compile el ensamblado de la aplicación y antes del empaquetado, para que la aplicación empaquetada lleve el ensamblado ofuscado.

Línea de comandos

Para aplicar el cifrado STREAM desde la línea de comandos:

babel myapp.exe --string stream

Tarea Babel de MSBuild

Para activar el cifrado STREAM con la tarea de MSBuild de Babel, establezca la propiedad StringEncryption como sigue:

<PropertyGroup> <StringEncryption>stream</StringEncryption> </PropertyGroup> <Babel StringEncryption="$(StringEncryption)" />

STREAM funciona junto con las demás protecciones. Puede combinarse con el cifrado de código (MSIL) y con la protección contra manipulación en el mismo ensamblado.

Protección contra manipulación y reescritura posterior a la compilación. La protección contra manipulación graba un hash de integridad de la imagen ofuscada. Cualquier paso que reescriba el ensamblado después de Babel (sobre todo una publicación recortada o NativeAOT, que vuelve a emitir el ensamblado administrado) cambia esos bytes y hace que la comprobación falle de inmediato en el arranque. Esto es inherente a la protección contra manipulación e independiente del algoritmo de cadenas (afecta por igual a XOR, HASH y STREAM): active la protección contra manipulación en las compilaciones que no se recorten ni se reescriban después con AOT, y recurra al cifrado de cadenas (más el cifrado de código) para las salidas recortadas o AOT.

Comparación de los algoritmos

Los tres algoritmos integrados son autónomos (descifran sin ninguna entrada externa), de modo que elegir entre ellos supone buscar un equilibrio entre el tiempo de carga, el tamaño de la salida y lo difícil que resulta recuperar las cadenas.

XORHASHSTREAM
CifradoXOR en línea con una clave entera por cadenaTabla comprimida y cifrada con el algoritmo de cifrado de la plataformaCifrado autenticado por cadena, estándar del sector
Cadenas conservadas como literalesSí (alteradas en su lugar)NoNo
Modelo de descifradoPor cadena, en cada accesoAnticipado: toda la tabla se descifra en el primer usoDiferido: cada cadena en su primer uso, y después en caché
Texto sin cifrar en memoriaUna cadena cada vezToda la tabla, durante toda la ejecuciónSolo las cadenas que realmente se usan
Etiqueta de integridad por cadena——Sí
Las cadenas idénticas se cifran de forma distintaNoNoSí
Rechaza el descifrado fuera de contexto (invocación mediante delegado)——Sí
Clave de descifradoEn línea, junto a la llamadaAlmacenada en la cabecera del blobNunca en línea: se reconstruye en tiempo de ejecución y se entrelaza con el flujo de control
Descifrador totalmente administrado (sin proveedor criptográfico de la plataforma; seguro con FIPS)NoNoSí
Tamaño relativo de la salidaEl mayor (los literales permanecen en el ensamblado)El menor (un único blob comprimido)Entre XOR y HASH
Coste relativo en tiempo de ejecuciónEl más bajoBajo, pero se paga por adelantado para todas las cadenasMayor por cadena, y solo se paga por las cadenas que se usan

Cuál elegir.

  • XOR: el más rápido y ligero, pero también el más débil. Las cadenas cifradas permanecen como literales en el ensamblado y junto a cada llamada hay una clave por cadena, de modo que una herramienta automática puede recuperarlas en una sola pasada. Elíjalo cuando el tiempo de carga importe más que la protección.
  • HASH: elimina los literales y empaqueta todo el conjunto en un único blob comprimido y cifrado (la salida más pequeña), con protección de la tabla contra manipulación. El coste es que toda la tabla se descifra de forma anticipada en el primer uso, de modo que todas las cadenas permanecen en memoria en texto sin cifrar durante el resto de la ejecución, y que su descifrador depende del proveedor criptográfico de la plataforma (consulte la nota sobre FIPS).
  • STREAM: el más resistente de los tres frente al análisis estático y al dinámico, con cifrado autenticado por cadena, sin descifrado global anticipado, sin clave en línea y con un único descifrador totalmente administrado que se publica sin cambios con NativeAOT y con recorte y al que FIPS no afecta. El coste de descifrado por cadena es mayor, pero solo se paga por las cadenas que la aplicación usa realmente, y en ningún momento está en memoria el conjunto completo de cadenas en texto sin cifrar. Prefiera STREAM para .NET moderno, para despliegues AOT, recortados o FIPS, y allí donde más importe la resistencia a la extracción masiva de cadenas.
Last updated on