Nebula.NET
Protección de distintos tipos de proyecto
Recetas para cada tipo de proyecto .NET — bibliotecas y paquetes NuGet, WPF/WinForms, ASP.NET Core y Blazor, MAUI, aplicaciones de consola y servicios, Unity, archivo único, F#/VB.
Nebula protege cualquier ensamblado .NET gestionado, pero los ajustes correctos dependen de cómo se cargue y se llame a tu código. Encuentra tu tipo de proyecto más abajo. La regla recurrente: todo lo que se resuelve por nombre en tiempo de ejecución (reflexión, serialización, enlace de XAML/Razor) debe preservarse — Nebula lo detecta automáticamente en su mayoría, y el resto puedes preservarlo de forma explícita.
Si tu caso exacto no aparece en la lista, el más parecido junto con Mantener tu aplicación funcionando y Resolución de problemas lo cubrirá — y siempre puedes preguntarnos.
Biblioteca de clases / SDK (consumida por otros)
Tu API pública es tu contrato — consérvala y ofusca las partes internas.
{ "inputs": ["bin/Release/net8.0/MyLib.dll"], "outputDirectory": "protected",
"preservePublicApi": true, "controlFlowObfuscation": true, "encryptStrings": true }
preservePublicApi: truemantiene con su nombre los tipos y miembros public/protected; todo lo internal/private se renombra.- ¿Envías varias bibliotecas que se llaman entre sí? Ofúscalas juntas con
crossAssemblyRename— consulta Varios ensamblados.
Paquete NuGet (.nupkg)
Apunta Nebula directamente al paquete — ofusca los ensamblados que contiene y vuelve a empaquetar un .nupkg protegido:
{ "inputs": ["bin/Release/MyLib.1.2.3.nupkg"], "outputDirectory": "protected", "preservePublicApi": true }
Aplicación de consola / servicio de Windows / demonio
No hay superficie pública que preservar, así que protege todo para obtener la máxima fuerza:
{ "inputs": ["bin/Release/net8.0/MyApp.dll"], "outputDirectory": "protected",
"preservePublicApi": false, "controlFlowObfuscation": true, "controlFlowIntensity": "aggressive",
"encryptStrings": true }
El punto de entrada se renombra de forma segura — el runtime localiza Main por el token de metadatos, no por el nombre.
WPF / WinForms (escritorio, XAML)
XAML se enlaza a propiedades, comandos y controladores de eventos por nombre de los view-models en tiempo de ejecución, y el diseñador de WinForms serializa los campos de los controles por nombre. Preserva lo que toca la capa de interfaz:
- Mantén
preservePublicApi: true(los miembros enlazados suelen ser públicos). - Excluye los tipos a los que se enlaza XAML si algún miembro enlazado no es público — por ejemplo, los view-models y sus propiedades enlazadas. Consulta exclusiones.
- No renombres tipos referenciados por nombre en XAML (
x:Class, convertidores,{x:Type}); la detección automática de Nebula captura la mayoría, pero prueba la aplicación en ejecución.
ASP.NET Core / Blazor / Web API
El enlace de modelos, el enrutamiento, el marcado Razor/Blazor y la serialización JSON se resuelven todos por nombre:
- Controladores / manejadores de API mínima / Razor Pages / componentes Blazor referenciados en el enrutamiento o el marcado — preserva (normalmente públicos;
preservePublicApi: true). - DTO / modelos de petición y respuesta — sus nombres de propiedad se convierten en campos JSON/XML, así que presérvalos (se detectan automáticamente cuando llevan atributos
System.Text.Json/Newtonsoft/DataContract; en caso contrario, exclúyelos). - La inyección de dependencias se basa en tipos (
AddScoped<IFoo, Foo>()) y es segura; el escaneo por convención/ensamblado por nombre requiere preservar los tipos escaneados.
Las partes internas (lógica de negocio, algoritmos) se pueden renombrar y aplanar el flujo de control con libertad — ahí está el valor.
.NET MAUI / Xamarin
Trátalo como WPF (enlace XAML) más la interoperabilidad de plataforma: preserva los view-models enlazados a XAML y cualquier nombre de [DllImport]/servicio de plataforma. Los puntos de entrada de [DllImport] se preservan automáticamente.
Unity
Unity serializa los campos public/[SerializeField] por nombre y puede llamar a métodos mediante SendMessage("Name"). Preserva los campos serializados y cualquier método destino de mensajes (anótalos — ver más abajo), y preserva las subclases de MonoBehaviour referenciadas por nombre en las escenas.
F# y VB.NET
Totalmente compatibles — Nebula trabaja a nivel de IL, así que el lenguaje no importa. F# emite miembros adicionales generados por el compilador; mantén autoDetect: true (el valor por defecto) y ejecuta tus pruebas contra la compilación protegida.
Aplicaciones de archivo único y autónomas
Ofusca los ensamblados gestionados, y luego deja que la publicación de archivo único agrupe las copias protegidas (compilar → ofuscar → dotnet publish --no-build). Dos notas:
- El auto-hash de la anti-manipulación no hace nada dentro de un paquete de archivo único (el ensamblado no tiene ruta en disco), así que ahí confía en el flujo de control + el cifrado de cadenas. Para disposiciones multiarchivo/carpeta autónoma, la anti-manipulación funciona con normalidad.
- Lo autónomo solo añade el runtime; no cambia cómo ofuscas tus ensamblados.
Salida con nombre seguro (strong-named) o firmada con Authenticode
La ofuscación reescribe el ensamblado, así que firma después de ofuscar — Nebula lo hace por ti:
{ "strongNameKeyFile": "keys/mykey.snk",
"authenticodeCertFile": "keys/cert.pfx", "authenticodeTimestampUrl": "http://timestamp.digicert.com" }
El nombre seguro se vuelve a aplicar al ensamblado protegido; Authenticode firma la salida final.
Código de licenciamiento / anti-piratería (como una comprobación de licencia)
Este es un objetivo prioritario — aplana la lógica de decisión para que no pueda leerse ni parchearse:
{ "controlFlowObfuscation": true, "controlFlowIntensity": "aggressive",
"controlFlowInclude": ["MyApp.Licensing.LicenseManager.Validate", "MyApp.Licensing.LicenseManager.CheckEdition"],
"encryptStrings": true }
Apunta a los métodos concretos con controlFlowInclude, cifra las cadenas que revelan las condiciones de las ramas y mantén funcionando cualquier autocomprobación de identidad de tipo ([Guid], Assembly.GetExecutingAssembly()) — Nebula preserva [Guid] y la identidad del ensamblado a través de la ofuscación.