2011-02-16 21 views
16

Mi caso es que tenemos un programa (exe) que iniciará otros programas si se encuentra en una carpeta en particular. Quiero asegurarme de que solo inicie programas firmados con nuestro certificado corporativo (aprobado por Verisign, etc.). Básicamente, solo iniciará los programas con el mismo certificado que él. No quiero enviar el certificado en sí.¿Cómo verificar programáticamente que un ensamble esté firmado con un certificado específico?

He estado buscando en la web y en el espacio de nombres del sistema y no he encontrado un ejemplo claro que lea los datos del certificado de un archivo y también lo valide, y pueda verificar contra otro archivo. Lo más cerca que he encontrado es Signtool y tener esta verificación en un exe por separado es una especie de punto menos. Sé que las cuestiones de Nombramiento fuerte no son útiles porque un archivo firmado digitalmente es diferente y se explica de manera útil aquí (http://blog.codingoutloud.com/2010/03/13/three-ways-to-tell-whether-an-assembly- dl-es-strong-named /) También hay otros ejemplos en SO que muestran el cifrado y la verificación de los datos sin procesar, pero no un ensamblaje donde se empaquetan juntos de alguna manera.

¿Alguna idea o sugerencia?

Respuesta

15

Aquí hay un post con ejemplos de código sobre cómo verificar las firmas de montaje:
http://blogs.msdn.com/b/shawnfa/archive/2004/06/07/150378.aspx

El código la muestra al final muestra cómo verificar si un ensamblado fue firmado por Microsoft o no; puede hacer lo mismo obteniendo el certificado token para el (los) certificado (s) de su empresa.

Actualización: usuario @Saber editó esto con la siguiente actualización, pero esa actualización fue rechazada por otros. Sin embargo, es un consejo muy válido, así que estoy volviendo a publicar su edición ya que SO no me deja aprobarlo:

Editar (gracias, OP): Si desea hacer esto de forma más segura (es decir, su programa es más inviolable), haga referencia a un ensamblaje en su programa que tenga un nombre fuerte con la clave relevante, luego use el token del ensamblado al que se hace referencia para compararlo con el token del ensamblado que realiza la llamada. Si utiliza una matriz de bytes (según el enlace), simplemente puede ser editada y modificada hexadecimamente.

+4

¿Por qué el voto a favor? _Leer_ la publicación de blog a la que me he vinculado, y verá que de hecho muestra cómo los enlaces de nomenclatura fuerte se unen a la firma de ensamblaje, y que _puede usar eso para verificar si un ensamblado ha sido firmado con un certificado específico. – KristoferA

+0

Sí, esto funciona bien y responde directamente a mi pregunta sobre la verificación de la firma sin lanzar un producto (aunque exhaustivo). Sería bueno si esto pudiera leer los detalles sobre el certificado de cualquier archivo firmado con Signtool y no solo ensamblados .NET. (Por ejemplo, instale Shield setup.exe y MSIs, etc.) Estaba buscando en la clase API de Windows pero no pude encontrar nada para decir con quién estaba firmado. Esto es lo suficientemente bueno sin embargo. Probablemente no necesite verificar al propietario del certificado, si un cliente ha aprobado el certificado o su autoridad, de todos modos está en su cabeza. – Aaron

+0

@Aaron su comprensión de los certificados es defectuosa. Si no valida el certificado, deseche sus cheques y no se moleste en implementarlos. No hay seguridad es mejor que seguridad rota ya que este último da una falsa sensación de seguridad. –

3

Existen dos tecnologías de firma para ensamblados .NET: strongnaming y Authenticode (el authenticode se usa para firmar PE y algunos otros archivos, no solo los ensamblados .NET). Se usan para diferentes propósitos. Los certificados se usan en Authenticode solo para autenticar al autor. Strongnaming no autentica al autor en absoluto.

Además de verificar la firma, el certificado debe ser validado para garantizar que fue emitido por el autor. La validación adecuada es un procedimiento complejo que implica la comprobación de CRL (lista de revocación de certificados) y OCSP (estado del certificado en línea).

Para realizar la verificación de la firma Authenticode necesita el componente de verificación Authenticode. Una de las opciones es usar el paquete PKIBlackbox de nuestro producto SecureBlackbox. El paquete incluye verificación Authenticode así como mecanismos completos de validación de certificados.

Tenga en cuenta que si no va a validar el certificado, no tiene sentido verificar la firma en absoluto, porque se puede crear un certificado autofirmado con el mismo Asunto, Número de serie, etc., y utilizarlo para firmar el ensamblaje forjado.

2

Puede probar tres opciones aquí.

1) El primero de ellos está utilizando la carga de la Asamblea como aquí:

Assembly myDll = 
    Assembly.Load("myDll, Version=1.0.0.1, Culture=neutral, PublicKeyToken=9b35aa32c18d4fb1"); 

Puede imprimir el formato hexadecimal de la clave pública y el símbolo de clave pública para un conjunto específico mediante el siguiente nombre seguro (Sn. exe) de comandos:

sn -Tp <assembly> 

Si usted tiene un archivo de clave pública, puede utilizar el siguiente comando (tenga en cuenta la diferencia en el caso de la opción de línea de comandos):

sn -tp <assembly> 

2) El segundo is mentioned here. Y use p/Invoke para tal problema.

3) También existe una tercera, más ágil y más compleja forma de hacerlo. Esta es una política de enlace . Puede tenerlo en cuenta en el caso de que deba proporcionar actualizaciones para una aplicación que ya está implementada. Cuando sale una nueva versión de un componente compartido de la que puede beneficiarse su aplicación, un archivo de política de la aplicación le permitirá proporcionar estos beneficios sin volver a compilar o reemplazar las instalaciones existentes.

Puede encontrar más información sobre esta función aquí:

http://msdn.microsoft.com/en-us/library/aa309359%28v=vs.71%29.aspx

http://ondotnet.com/pub/a/dotnet/2003/03/17/bindingpolicy.html

0

Creo que hay una manera de usar un nombre seguro con el propósito de "Confianza". 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 del cargador (la aplicación que carga estos ensamblados/programas) 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/programa a través del nombre completo del ensamblaje?

<PackageHandlers> 
    <PackageHandler> 
    <Package type="Package1" assembyName="SomeAssembly" publickey="d45755dbb8b44e59" /> 
    </PackageHandler> 
</PackageHandlers> 
Cuestiones relacionadas