Siempre he entendido el propósito de firmar un ensamblaje para que sea un control en tiempo de ejecución para garantizar que las actualizaciones del código provengan de una fuente confiable. Efectivamente están tratando de evitar este tipo de escenario:
Compro una biblioteca de encriptación de la Compañía A, poco después, la Compañía B obtiene mis datos de correo electrónico y me envía una actualización gratuita al ensamblaje que pretende ser un importante error de seguridad arreglar desde la Compañía A cuando realmente inyecta un método oculto en mi código que envía todos los datos que intentaba cifrar a los servidores de la compañía B. Asumiendo que soy un idiota y agregando ciegamente este nuevo dll al directorio bin de mi aplicación, el hecho de que esto no haya sido firmado con la misma clave privada que la versión anterior se detectará en el tiempo de ejecución, causando una excepción y protegiendo mis datos.
Por lo tanto, no veo ninguna razón para publicar la clave pública fuera del ensamblado ya que no se supone que garantice que el archivo original proviene de un proveedor específico, solo que todas las versiones posteriores provienen del mismo lugar que el primero.
Wikipedia dice casi lo mismo (solo en pocas palabras).
Editado para añadir más información en un intento de hacer esto más claro ...
Creo que lo que hay que aclarar primero es que los pares de claves públicas y privadas son únicos. Eso significa que conocer la clave pública no es suficiente información para reconstruir el ensamblaje de manera que pase los mismos controles hash.
Por lo tanto, usuario Z que está utilizando una biblioteca de cifrado de la empresa A que se encuentra en su carpeta bin de aplicaciones. Para ello se hace referencia a la DLL de la siguiente manera:
Encryption, Version=1.0.0.0, Culture=neutral, PublicKeyToken=bcd6707151635d07"
El propósito de la clave pública es que nos proporcione three benefits la que me ocuparé de uno a la vez.
En primer lugar, proporciona un nombre único para el ensamblado; esto no nos proporciona seguridad adicional pero sí detiene el estilo C dll Hell, donde dos compañías diferentes podrían lanzar dos bibliotecas diferentes llamadas Encyption versión 1.0.0.0 y usted no podría para almacenarlos en el mismo directorio ya que no hay forma de diferenciarlos.
En segundo lugar, evita el escenario que describí en mi publicación original. Es imposible para la empresa B crear otra versión de la biblioteca de cifrado que también sea la versión 1.0.0.0 y tenga la misma clave pública (para que el nombre completo coincida y usted llame a su código en lugar de a la compañía A). No pueden hacer esto porque si su clave pública coincide, entonces la clave privada también debe coincidir (ya que cada par es único). La única forma en que pueden hacer coincidir la clave privada es comprometiendo la seguridad de la Compañía A.
Finalmente asegura la integridad del archivo (ya sea por corrupción o inyección de código malicioso). El archivo dll es hash en el tiempo de ejecución (cuando es privado y en la carpeta bin de la aplicación) o el tiempo de instalación (cuando lo coloca en el GAC) utilizando la clave pública y ese hash se compara con el hash que fue censurado por el privado clave y almacenada en el conjunto. This page tiene algunos diagramas y más detalles. Una vez más, la única forma de falsificar este hash es conocer la clave privada.
Por lo tanto, para cubrir el escenario específico que describí anteriormente, pretendo que soy la Compañía B tratando de suministrar al Usuario Z una versión maliciosa de la DLL de cifrado. Mi primer intento es simplemente crear mi propio dll con el nombre Encryption y la Versión 1.0.0.0 y firmarlo con mi propio par de claves. Lamentablemente, no puedo cambiar el código de referencia en la aplicación del Usuario Z, por lo que falla la verificación del nombre completo y no se carga. "Está bien", me dice mientras me giro el bigote, "Simplemente cambiaré la clave pública de mi ensamblaje para que coincida con la de la Compañía A". Una vez hecho esto, el nombre pasa, pero la comprobación de hash fallará porque la aplicación del usuario Z no podrá descifrar el hash almacenado en el conjunto (que se cifró con la clave privada de la empresa B) con la clave pública (empresa A's) que ha sido suministrado. Por lo tanto, la única forma en que la Compañía B puede crear una biblioteca que pretende ser la Compañía A es conocer la clave privada de la Compañía A. Ninguna de estas comprobaciones de seguridad depende de que la Empresa A publique la clave pública en ningún otro lugar, excepto en la versión original del ensamblado.
Tenga en cuenta también que todas estas características no aseguran (y no aseguran) que el ensamblaje original provino de la empresa A, que es manejado por otros sistemas como Verisign o el servicio Authenticode de Microsoft, solo se aseguran una vez que ha hecho referencia al ensamblaje, solo la empresa A puede realizar cambios en ese código.
Eso no está del todo claro y no se menciona explícitamente en el artículo vinculado.Para hacer todo esto, el tiempo de ejecución necesita almacenar en caché los hashes de cada ensamblaje y verificarlo al cargar el ensamblaje. ¿Realmente hace esto? – sharptooth
De acuerdo con "CLR via C#" por Jeffery Richter lo hace cuando el ensamblaje no está en el GAC. Citando del libro: "Cuando los ensamblajes fuertemente nombrados se cargan desde una ubicación distinta al GAC, el CLR compara los valores hash cuando se carga el ensamblaje. En otras palabras, se ejecuta un hash del archivo cada vez que se ejecuta una aplicación y se carga el ensamblaje Este golpe de rendimiento es una compensación por estar seguro de que el contenido del archivo ensamblado no ha sido alterado ". –
También agregaré esta cita de "C# a través del CLR" (libro muy recomendado por cierto): "Importante: este mecanismo asegura solo que el contenido de un archivo no ha sido manipulado. El mecanismo no le permite diga quién es el editor a menos que esté absolutamente seguro de que el editor produjo la clave pública que tiene y está seguro de que la clave privada del editor nunca se vio comprometida ". Por lo tanto, incluso si publican la clave pública por separado del ensamblado, aún no le permite verificar el editor. –