2009-04-28 22 views
5

De la descripción de la utilidad sn.exe y this question veo que se agrega una copia de la clave pública a cada ensamblado firmado con el nombre seguro. Esto es suficiente para validar que el ensamblado binario no ha sido alterado.¿Debo publicar la clave pública desde el archivo .snk?

Pero, ¿cómo se verifica que el ensamblaje dado se firmó realmente con un par de claves determinado y compilado por una empresa determinada? Cualquiera podría generar su propio par de llaves, producir algún ensamblaje y firmarlo con su par de llaves. ¿Debo publicar la clave pública para que los que quieran verificar el origen del ensamblaje puedan comparar las claves públicas? si es así, ¿cuál es la mejor manera de hacerlo?

Respuesta

5

No, no es necesario para publicar su clave pública exterior del conjunto, ya que es ordenado y se almacena como una muestra además de la referencia dentro de la aplicación del cliente:

AssemblyName, Version=1.0.0.0, Culture=neutral, PublicKeyToken=bcd6707151635d07" 

Esto proporciona un método para asegurar que todas las versiones futuras del ensamblado se compilan contra el mismo par de claves y, por lo tanto, del mismo editor.

Más detalles sobre cómo tener esta información impide que otra fuente se haga pasar por la que se puede encontrar en mi otra respuesta.

3

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.

+0

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

+1

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 ". –

+0

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. –

2
  1. Puede ir a un proveedor de certificados de terceros (por ejemplo, VeriSign) y comprar un certificado de ellos (Code Signing At Verisign).
  2. Utiliza el certificado que tiene el nombre de su empresa, URL, etc. en él para firmar su código.
  3. Te descargo la aplicación y miro la lista de certificados con los que se ha iniciado sesión.
  4. Utilizo su certificado, vuelvo a VeriSign y verifico que el certificado ha sido emitido a MyCompany, LLC.
  5. Veo los certificados que se han utilizado para emitir su certificado y verifico que VeriSign es uno de ellos (Windows viene con pocos certificados confiables instalados).

Resumen:
Usted no sólo verificar que el código no ha sido vanamente con, sino que también fue firmado con un certificado emitido por una parte de su confianza.

+1

Entiendo todo esto y esto es lo que realmente hacemos. Pero esto no tiene nada que ver con los nombres fuertes y los archivos .snk, ¿no? – sharptooth

+0

Ha pasado un tiempo desde que hice eso. Pero IIRK utiliza la clave pública de su certificado para firmar su código. Es decir. .snk se produce/exporta desde el archivo .cer que obtiene de VeriSign utilizando makecert.exe. Tal que el código de firma en realidad hace dos cosas: 1) impide que el código se modifique con (protección) 2) autentica al publicador. –

Cuestiones relacionadas