¿Se puede usar un nombre fuerte para ensamblar para verificar el autor del ensamblaje?

He estado leyendo el artículo correcto en MSDN, Ensambles de nombres fuertes y una pregunta relacionada sobre Desbordamiento de stack, Comprobando que un ensamble tenga un nombre seguro .

  1. ¿En qué medida se puede verificar un ensamble de nombre fuerte para evitar la manipulación?
  2. ¿Es posible usar nombres fuertes para verificar un autor de ensamblaje?

La primera pregunta surge después de leer el artículo de CSharp411. Preguntas frecuentes sobre la Asamblea de .NET – Parte 3: Nombres y firmas fuertes , que menciona esto, entre otros problemas de uso de nombres fuertes:

No se puede detener el reemplazo completo. Los nombres fuertes no pueden evitar que un pirata informático elimine la firma del nombre fuerte, modifique maliciosamente su ensamblaje, lo vuelva a firmar con su propia clave y luego pase su ensamblaje como suyo”.

La segunda pregunta intenta encontrar las diferencias entre nombres fuertes y otros esquemas de firma como, por ejemplo, Authenticode . El mismo artículo de MSDN menciona estados tempranos:

Tenga en cuenta, sin embargo, que los nombres sólidos en sí mismos no implican un nivel de confianza como el proporcionado, por ejemplo, mediante una firma digital y un certificado de respaldo.

¿Estoy tratando de usar nombres fuertes para mucho más de lo que fue creado? ¿Fue un nombre fuerte creado solo para evitar conflictos de nombres o un nuevo tipo de “Infierno de GAC DLL”?

Cuando firma un ensamblado con un nombre seguro basado en una clave privada que usted crea, esto tiene los siguientes beneficios:

  • Un nombre seguro garantiza la singularidad de la identidad de un ensamblaje agregando un token de clave pública y una firma digital al ensamblaje.
  • Se puede asociar un nombre seguro a una clave pública para probar que el ensamblado proviene del editor con esa clave pública, y solo ese editor.
  • Un nombre fuerte proporciona una fuerte verificación de integridad. Pasar las comprobaciones de seguridad de .NET Framework garantiza que el contenido del ensamblado no se modificó desde la última vez que se construyó.

¿Es posible usar nombres fuertes para verificar un autor de ensamblaje?

Sí, como se mencionó anteriormente, strong-naming puede verificar el último autor de la reunión. Pero no verifica el autor original. Si un atacante reemplaza el nombre fuerte de su ensamblaje, todo lo que se puede verificar es que no fue el último autor del ensamblaje. Si elimina el nombre fuerte, entonces no se puede hacer ninguna verificación del autor.

¿En qué medida se puede verificar un ensamble de nombre fuerte para evitar la manipulación?

El siguiente código de C # verifica que un atacante no ha manipulado el token de clave pública que se escribió en su ensamblado cuando aplicó el nombre seguro. No evita la manipulación, pero puede detectar algunos tipos de manipulación. El siguiente método acepta una matriz de bytes que contiene el token de clave pública y lo compara con el token real del ensamblado. Tenga en cuenta que para que esta técnica sea efectiva, su ofuscador de elección debe encriptar la cadena que contiene su token de clave pública, y solo descifrarla sobre la marcha a medida que se utiliza. Y también tenga en cuenta que necesita tener permiso de FullTrust para que este código funcione porque usa reflexión debajo del capó.

// Check that public key token matches what's expected. private static bool IsPublicTokenOkay_Check(byte [] tokenExpected) { // Retrieve token from current assembly byte [] tokenCurrent = Assembly.GetExecutingAssembly().GetName().GetPublicKeyToken(); // Check that lengths match if (tokenExpected.Length == tokenCurrent.Length) { // Check that token contents match for (int i = 0; i < tokenCurrent.Length; i++) if (tokenExpected[i] != tokenCurrent[i]) return false; } else { return false; } return true; } 

Siempre que ejecute una versión de .NET Framework antes de .NET 3.5 SP1, también puede forzar la verificación de la firma fuerte del nombre en caso de que un atacante elimine el nombre fuerte o de que se desactive la verificación del nombre seguro en el registro. El siguiente código muestra una llamada a un método estático de otra clase llamada NativeMethods. Aquí es donde se aplicará la verificación.

 // Check that this assembly has a strong name. private bool IsStrongNameValid_Check() { byte wasVerified = Convert.ToByte(false); byte forceVerification = Convert.ToByte(true); string assemblyName = AppDomain.CurrentDomain.BaseDirectory + AppDomain.CurrentDomain.FriendlyName; return NativeMethods.CheckSignature(assemblyName, forceVerification, ref wasVerified); } 

La verificación de firma real se realiza usando P / Invoke como se muestra a continuación. El uso de la API StrongNameSignatureVerificationEx es bastante intrincado: para una explicación decente, consulte esta entrada en el blog .

 // P/Invoke to check various security settings // Using byte for arguments rather than bool, // because bool won't work on 64-bit Windows! [DllImport("mscoree.dll", CharSet=CharSet.Unicode)] private static extern bool StrongNameSignatureVerificationEx(string wszFilePath, byte fForceVerification, ref byte pfWasVerified); // Private constructor because this type has no non-static members private NativeMethods() { } public static bool CheckSignature(string assemblyName, byte forceVerification, ref byte wasVerified) { return StrongNameSignatureVerificationEx(assemblyName, forceVerification, ref wasVerified ); } 

Tenga en cuenta que esto no funcionará de manera predeterminada para las aplicaciones que usan .NET 3.5 SP1 o superior, que tiene la función de omisión de nombre seguro . Es posible desactivar esta función para su aplicación agregando una configuración a su archivo de configuración. Pero, por supuesto, cualquier atacante con acceso de lectura / escritura a ese archivo de configuración puede revertir su decisión.

Authenticode confía en una autoridad de certificación de terceros para la validación de certificados. Los nombres fuertes funcionan como un certificado autofirmado y se pueden tratar como tales. Utiliza firmas digitales estándar, pero el problema radica en verificar que la clave pública del autor del ensamblaje sea válida. Si lo obtiene por separado a través de un canal de confianza del autor y usted confía en ese canal, entonces sí, puede verificarlo como un certificado autofirmado.

Siempre que esté seguro de que el autor mantiene la clave privada de nombre seguro y de que conoce la clave pública del autor, puede asegurarse de que no se manipule (en la medida en que pueda asegurarse de que no se manipule indebidamente un correo electrónico firmado digitalmente). Por cierto, no me malinterpreten: la cita es completamente cierta y un atacante puede renunciar fácilmente al ensamblaje o eliminar la firma existente. Sin embargo, el conjunto resultante tendrá una firma digital ** diferente * que se puede comparar con el original (si tiene la clave pública original).

En este caso, es similar a un certificado autofirmado. Si de alguna manera puede estar seguro de la clave pública del autor, puede verificar la autoridad. Sin embargo, a diferencia de Authenticode, que depende de una autoridad de certificación, no existe una forma directa y definida por el sistema para distribuir la clave pública.

Creo que los nombres fuertes son útiles para las versiones y se pueden usar para ayudar a establecer niveles de confianza para la edición de seguridad de acceso de código: pero no puede usarlos para verificar que el ensamblaje sea creado por alguien de confianza o por un autor específico. Mira el comentario de @RoadWarrior y la respuesta de @ RoadWarrior a esta pregunta.

Un nombre fuerte para su ensamblaje no lo hace a prueba de manipulaciones.
Editar: vea los comentarios de @RoadWarrior y @divo. Si su aplicación está verificando la clave privada original del autor de la asamblea y forzando una fuerte verificación del nombre, mi statement es incorrecta. Sin embargo, si el atacante tiene acceso a todos los ensamblajes en su aplicación y / o está usando una verificación de nombre fuerte provista de manera gratuita de la CLR, entonces estoy de acuerdo con lo que dije.

Esto puede ser subvertido por un atacante determinado .

Hace un tiempo, leí una discusión acerca de los nombres y la seguridad sólidos que me llevaron a creer que para los ensamblajes que producimos, el authenticode era una mejor garantía para nuestros clientes de que el ensamblaje provenía de una fuente confiable.

Creo que hay una forma de usar un nombre fuerte para “Confiar”. Entiendo que Microsoft solo recomienda un nombre seguro para garantizar que los contenidos del ensamblado no se hayan modificado y sugiere el uso de “Authenticode” para la confianza.

Pero si la aplicación de cargador (la aplicación que carga estos ensamblados / progtwigs) mantiene una lista Encriptada de “Conjuntos” que puede cargar; ¿eso no resolvería el problema de “Confianza”?

Por ejemplo, el cargador de paquetes puede mantener el nombre del ensamblado con las claves públicas y carga el ensamblaje / progtwig a través del nombre completo del ensamblaje.