¿Cómo corregir el error "El ensamblado al que se hace referencia no tiene un nombre seguro"?

242

Agregué un ensamblado con un nombre débil a mi proyecto de Visual Studio 2005 (que tiene un nombre fuerte). Ahora recibo el error:

"El ensamblado al que se hace referencia 'xxxxxxxx' no tiene un nombre seguro"

¿Debo firmar este ensamblaje de terceros?

ng5000
fuente
1
Esto puede sonar como una sugerencia tonta, pero si encuentra que su ensamblaje no se firma sin importar lo que haga, verifique la configuración de compilación; recuerde que VS no borra otras arquitecturas (cualquier CPU, x64, etc.) cuando reconstruye / limpia, por lo que podría estar viendo un archivo DLL obsoleto de otra arquitectura.
jrh

Respuestas:

213

Para evitar este error, podrías:

  • Cargue el ensamblaje dinámicamente, o
  • Firmar la asamblea de terceros.

Encontrará instrucciones sobre cómo firmar ensamblados de terceros en .NET-fu: Firmar un ensamblado sin firmar (sin firma de retraso) .

Firma de Asambleas de terceros

El principio básico para firmar una fiesta de sed es

  1. Desmontar el ensamblaje utilizando ildasm.exey guardar el lenguaje intermedio (IL):

    ildasm /all /out=thirdPartyLib.il thirdPartyLib.dll 
  2. Reconstruir y firmar el ensamblaje:

    ilasm /dll /key=myKey.snk thirdPartyLib.il

Arreglando referencias adicionales

Los pasos anteriores funcionan bien a menos que su ensamblado de terceros ( A.dll ) haga referencia a otra biblioteca ( B.dll ) que también tiene que estar firmada. Puede desmontar, reconstruir y firmar A.dll y B.dll utilizando los comandos anteriores, pero en el tiempo de ejecución, la carga de B.dll fallará porque A.dll se creó originalmente con una referencia a la versión sin firmar de B.dll .

La solución a este problema es parchear el archivo IL generado en el paso 1 anterior. Deberá agregar el token de clave pública de B.dll a la referencia. Obtienes este token llamando

sn -Tp B.dll 

que te dará el siguiente resultado:

Microsoft (R) .NET Framework Strong Name Utility  Version 4.0.30319.33440
Copyright (c) Microsoft Corporation.  All rights reserved.

Public key (hash algorithm: sha1):
002400000480000094000000060200000024000052534131000400000100010093d86f6656eed3
b62780466e6ba30fd15d69a3918e4bbd75d3e9ca8baa5641955c86251ce1e5a83857c7f49288eb
4a0093b20aa9c7faae5184770108d9515905ddd82222514921fa81fff2ea565ae0e98cf66d3758
cb8b22c8efd729821518a76427b7ca1c979caa2d78404da3d44592badc194d05bfdd29b9b8120c
78effe92

Public key token is a8a7ed7203d87bc9

La última línea contiene el token de clave pública. Luego debe buscar en el IL de A.dll la referencia a B.dll y agregar el token de la siguiente manera:

.assembly extern /*23000003*/ MyAssemblyName
{
  .publickeytoken = (A8 A7 ED 72 03 D8 7B C9 )                         
  .ver 10:0:0:0
}
Dirk Vollmar
fuente
2
Por lo tanto, firmar el ensamblaje es una opción, no deseo cargar el ensamblado dinámicamente ni firmarlo. Sé que los nombres fuertes se refieren al Caché de la Asamblea Global (GAC). A pesar de eso, no quiero que mis ensamblajes formen parte del GAC y tampoco son COM-visibles. Recuerdo recordar parcialmente algo que podemos hacer que permitirá el uso de este ensamblado sin firmarlo. Está en algún lugar de las propiedades de opciones más o menos. ¿Estoy fuera de camino queriendo seguir ese camino?
Will Marcouiller
27
Puede usar ensamblajes sin firmar si su ensamblaje también está sin firmar.
DO
2
El enlace a .NET-fu es un recurso increíble
TheDude
2
Aunque los pasos anteriores funcionarán en "la mayoría" de las situaciones, es increíblemente lento y propenso a errores y falla con referencias de ensamblaje de amigos, entre otras cosas. Simplemente use esta utilidad para hacerlo todo automáticamente (enchufe descarado): stackoverflow.com/a/19459609/564726
BrutalDev
1
@Roel He detallado el proceso aquí delabs.io/the-12th-labor-of-a-net-developer-part-4
TheDude
98

Expanda el archivo de proyecto que está utilizando el proyecto que no "tiene una clave de nombre .snksegura " y busque el archivo (.StrongNameKey).

Busque este archivo en el Explorador de Windows (solo para saber dónde está).

De vuelta en Visual Studio en el proyecto que no "tiene una clave de nombre segura", haga

  • Haga clic derecho en el archivo del proyecto
  • Seleccionar propiedades
  • Seleccione "pestaña Firma" (a la izquierda)
  • Haga clic en la casilla de verificación "Firmar el ensamblado"
  • Luego <Browse>al .snkarchivo que encontraste anteriormente

Eso debería hacer el truco. Esto resolvió un problema para mí para un proyecto usando un formulario dentro de otro proyecto en la misma solución.

Espero que ayude.

MrOli3000
fuente
Si no quisiera firmar mi ensamblaje, ¡no lo habría firmado desde el principio!
mohas
Si no encuentra el archivo .snk: Abra las propiedades del proyecto (del proyecto que utiliza el proyecto con el error "nombre seguro"), ficha Firma. Allí verá el archivo utilizado para firmar el proyecto (no siempre es un archivo con la extensión .snk). Simplemente copie esta configuración al otro proyecto.
Coder14
Como señala MrOli3000, funciona SOLO si hay una solución a la que le falta el archivo de clave de nombre seguro. Si hay varios proyectos que harían referencia al proyecto sin firmar, es mejor que cree un nuevo archivo de clave de nombre seguro para evitar conflictos. En mi caso, la solución no se compiló, e iba en círculos tratando de solucionarlo. A partir de VS2017, el formato es .pfx y no .snk, pero los pasos son los mismos: haga clic con el botón derecho en la solución y elija las propiedades. De las pestañas que figuran a la izquierda, elija "Firma". Haga clic en la casilla de verificación y seleccione nuevo ... ¡proporcione un nombre! ¡y voilá! está hecho!)
Raj
59

Estaba buscando una solución para el mismo problema y la opción de desmarcar "Firmar el ensamblaje" funciona para mí:

ingrese la descripción de la imagen aquí

(Como puede observar, la captura de pantalla proviene de VS2010, pero con suerte ayudará a alguien)

Mars Robertson
fuente
No verifico esta configuración en mi proyecto MVC. Pero todavía se queja de una de las dependencias. ¿Hay alguna otra configuración para MVC?
Hamid Mayeli
51

He escrito una herramienta para ensamblar signos de nombre automático, incluidos aquellos para los que no tiene el código fuente o proyectos que han sido abandonados. Utiliza muchas de las técnicas descritas en las respuestas de una manera simple sin ninguno de los defectos o inconvenientes de las herramientas existentes o las instrucciones con fecha.

http://brutaldev.com/post/2013/10/18/NET-Assembly-Strong-Name-Signer

Espero que esto ayude a cualquiera que necesite firmar un ensamblaje de terceros sin tener que saltar a través de los aros para llegar allí.

BrutalDev
fuente
40

Puede usar ensamblajes sin firmar si su ensamblaje también está sin firmar.

Alexandr Nikitin
fuente
23

Firmar la asamblea de terceros funcionó para mí:

http://www.codeproject.com/Tips/341645/Referenced-assembly-does-not-have-a-strong-name

EDITAR : he aprendido que es útil publicar pasos en caso de que el artículo vinculado ya no sea válido. Todo el crédito va a Hiren Khirsaria :

  1. Ejecute el símbolo del sistema de Visual Studio y vaya al directorio donde se encuentra su DLL.

    For Example my DLL is located in D:/hiren/Test.dll

  2. Ahora cree el archivo IL usando el comando a continuación.

    D:/hiren> ildasm /all /out=Test.il Test.dll (este comando genera la biblioteca de códigos)

  3. Genere una nueva clave para firmar su proyecto.

    D:/hiren> sn -k mykey.snk

  4. Ahora firme su biblioteca usando el ilasmcomando.

    D:/hiren> ilasm /dll /key=mykey.snk Test.il

mateuscb
fuente
Su enlace hizo el truco! ¡Gracias! Y explica cómo crear mykey.snk (otras respuestas no dicen cómo)
Nicolas VERHELST
15

Cómo firmar un ensamblado de terceros sin firmar

  1. Abra el símbolo del sistema del desarrollador para Visual Studio. Esta herramienta está disponible en sus programas de Windows y se puede encontrar utilizando la búsqueda predeterminada de Windows.
  2. Asegúrese de que su solicitud tenga acceso a las siguientes herramientas ejecutándolas una vez: sn ildasmyilasm
  3. Navegue a la carpeta donde se encuentra su Cool.Library.dll
  4. sn –k Cool.Library.snk para crear un nuevo par de claves
  5. ildasm Cool.Library.dll /out:Cool.Library.il desmontar la biblioteca
  6. move Cool.Library.dll Cool.Library.unsigned.dll para mantener la biblioteca original como respaldo
  7. ilasm Cool.Library.il /dll /resource=Cool.Library.res /key=Cool.Library.snk volver a montar la biblioteca con un nombre seguro
  8. powershell -command "& {[System.Reflection.AssemblyName]::GetAssemblyName($args).FullName} Cool.Library.dll"para obtener el nombre completo de la asamblea. Necesitará este bit si tiene que hacer referencia a la DLL en archivos de configuración externos como web.config o app.config.
Martin Devillers
fuente
6

Tuve este problema para una aplicación que tenía un nombre fuerte y luego tuve que cambiarla para hacer referencia a un ensamblaje sin nombre, así que desmarqué 'Firmar el ensamblado' en la sección Firma de las propiedades del proyecto, pero aún se quejó. Pensé que tenía que ser un artefacto en algún lugar que causara el problema, ya que hice todo lo demás correctamente y fue solo eso. Encontré y eliminé la línea: [assembly: AssemblyKeyFile ("yourkeyfilename.snk")] de su archivo assemblyInfo.cs. Entonces no hay quejas después de eso.

Joe
fuente
¡Gracias! Debido a su respuesta, lo volví a verificar para mi problema (ClosedXML) y encontré también el paquete nuget ClosedXML.Signed.
Kiryl
6

Me encontraba con esto con un ServiceStack dll que había instalado con nuget. Resulta que había otro conjunto de dlls disponibles que estaban etiquetados como firmados. No será la respuesta para todos, pero es posible que solo necesite verificar una versión firmada existente de su ensamblaje.ServiceStack.Signed

Henry Crans
fuente
2

Para mí, mi problema era que tenía dos de los mismos paquetes NuGet instalados con diferentes versiones.

Demodave
fuente
2

Eliminar la marca de verificación "Firmar el ensamblaje" debajo de la pestaña "Firma" funciona como dijo @Michal Stefanow.

Agregar aquí es la forma más sencilla de firmar sus propios archivos y / o los archivos de otras personas. Solo necesita agregar esta línea debajo de la "Línea de comando del evento posterior a la compilación":

"C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\bin\signtool.exe" sign /f "$(ProjectDir)\YourPfxFileNameHere.pfx" /p YourPfxFilePasswordHere /d "Your software title here" /du http://www.yourWebsiteHere.com /t http://timestamp.verisign.com/scripts/timstamp.dll /v "$(BaseOutputPath)$(TargetFileName)"

Puede firmar los archivos de otras personas o sus propios archivos y todos los que desee.

ingrese la descripción de la imagen aquí

Pabinator
fuente
55
Este es un tipo diferente de firma. Lo que pregunta el OP es cómo firmar un ensamblado .NET con un nombre seguro. Muestra cómo firmar un ejecutable con un certificado de firma de código. Cosas diferentes.
Blue Toque el
2

Antigua pregunta, pero me sorprende que nadie haya mencionado ilmerge todavía. ilmerge es de Microsoft, pero no se envía con VS o los SDK. Sin embargo, puedes descargarlo desde aquí . También hay un repositorio de github . También puede instalar desde nuget:

PM>Install-Package ilmerge

Usar:

ilmerge assembly.dll /keyfile:key.snk /out:assembly.dll /targetplatform:v4,C:\Windows\Microsoft.NET\Framework\v4.0.30319 /ndebug

Si es necesario, puede generar su propio archivo de claves utilizando sn (de VS):

sn -k key.snk
Jahmic
fuente
1
Tuve el problema con WireMock.Net, finalmente lo puse a funcionar, pero me tomó un poco de tiempo descubrir los comandos de PowerShell. En particular, todo el conjunto de argumentos / lib para que ILMerge finalmente firme el ensamblado.
François
1> Register-PackageSource -ProviderName NuGet -Name NuGet -Location http://www.nuget.org/api/v2
François
2> Install-Package -Name ILMerge
François
3> $env:path += ';C:\Program Files\PackageManagement\NuGet\Packages\ilmerge.2.14.1208\tools'
François
4> ILMerge.exe .\packages\WireMock.Net.1.0.4.2\lib\net452\WireMock.Net.dll /keyfile:key.snk /out:WireMock.Net.dll /targetplatform:v4,C:\Windows\Microsoft.NET\Framework\v4.0.30319 /ndebug /lib:.\packages\Newtonsoft.Json.10.0.3\lib\net45\ /lib:.\packages\Handlebars.Net.1.9.0\lib\net40 /lib:.\packages\SimMetrics.Net.1.0.4\lib\net45 /lib:.\packages\Microsoft.Owin.2.0.2\lib\net45 /lib:.\packages\Owin.1.0\lib\net40 /lib:.\packages\Microsoft.Owin.Hosting.2.0.2\lib\net45 /lib:.\packages\MimeKitLite.2.0.1\lib\net45 /lib:.\packages\XPath2.1.0.5.1\lib\net40 /lib:.\packages\RestEase.1.4.4\lib\net45
François
1

Situación: tenía el proyecto A, B, C, D en la solución X, Y

Proyecto A, B, C en X Proyecto A, C, D en Y

Necesito usar el proyecto C en el proyecto A, pero luego no lo uso. En bin Debug, el proyecto A tenía C.dll.

Si compilo la solución X, todo bien (en esta solución elimino la referencia A -> C.), pero en la solución Y obtengo este problema.

La solución es eliminar C.dll en el proyecto A bin Debug

Martin9032
fuente
0

Primero asegúrese de que todos los paquetes nuget estén en la misma versión en todos los proyectos de su solución. por ejemplo, no desea que un proyecto haga referencia a NLog 4.0.0.0 y otro proyecto haga referencia a NLog 4.1.0.0. Luego intente reinstalar paquetes nuget con

Update-Package -reinstall

Tuve 3 asambleas de terceros a las que hacía referencia mi asamblea A y solo 2 fueron incluidas en las referencias de mi asamblea B que también hacía referencia a A.

El comando de paquete de actualización agregó la referencia faltante al ensamblado de terceros y el error desapareció.

Markus
fuente