← Todos los artículos

NuGet cambia el certificado de Microsoft: revisa trustedSigners antes de que falle tu restore

Microsoft anunció un nuevo certificado para firmar paquetes NuGet. Revisa si tu política fija huellas, añade la nueva y prueba la restauración en CI.

24 de septiembre de 2026 · · 7 min de lectura
Puerta transparente de verificación que valida un paquete de software en una cadena de suministro, con certificados antiguos y uno nuevo iluminado en una bandeja segura

El 23 de septiembre de 2026, Microsoft anunció que un nuevo certificado X.509 pasaría a ser el predeterminado para firmar como autor sus paquetes NuGet. Durante la transición, los paquetes nuevos pueden aparecer firmados con la nueva huella; los paquetes que ya estaban firmados conservan su firma anterior. No es una actualización general del SDK ni un aviso de compromiso: es un cambio de identidad criptográfica que importa cuando una política local permite solo una lista cerrada de certificados.

La pregunta operativa no es «¿debo actualizar todos mis paquetes?», sino «¿mi restore o mi verificación acepta la nueva huella sin dejar de aceptar paquetes históricos?». El anuncio oficial del equipo de NuGet limita el impacto explícito a dos casos: una política de firmantes permitidos que incluye a Microsoft, o una llamada a dotnet nuget verify que fija huellas de certificado.

Si no tienes ninguno de esos controles, Microsoft indica que los paquetes firmados con el nuevo certificado deberían instalarse como antes. Aun así, conviene comprobarlo en el runner que realmente hace el restore, no solo en la estación de desarrollo.

Las huellas que deben quedar en tu política

La huella SHA-256 nueva es:

9A1B131BEE0605433056A4EA3815478A8E177961A968C6C0027C1093D1FEB630

La huella que el aviso identifica como «certificado actual/anterior» en su texto es:

566A31882BE208BE4422F7CFD66ED09F5D4524A5994F50CCC8B05EC0528C1353

Ambas cadenas tienen 64 caracteres hexadecimales. El ejemplo de política de Microsoft incluye también dos certificados anteriores, que deben conservarse si aparecen en tu configuración:

3F9001EA83C560D712C24CF213C3D312CB3BFF51EE89435D3430BD06B5D0EECE
AA12DA22A49BCE7D5C1AE64CC1F3D892F150DA76140F210ABD2CBFFCA2C18A27

No sustituyas automáticamente la lista por solo la huella nueva. Los paquetes históricos no cambian de firma, y borrar certificados permitidos puede romper una restauración legítima. Conserva los valores que tu organización ya haya aprobado y añade el nuevo después de revisar su origen.

En XML, una entrada de autor puede quedar así, siempre que esos cuatro certificados sean los que tu política necesite:

<configuration>
  <config>
    <add key="signatureValidationMode" value="require" />
  </config>
  <trustedSigners>
    <author name="Microsoft">
      <certificate fingerprint="3F9001EA83C560D712C24CF213C3D312CB3BFF51EE89435D3430BD06B5D0EECE" hashAlgorithm="SHA256" allowUntrustedRoot="false" />
      <certificate fingerprint="AA12DA22A49BCE7D5C1AE64CC1F3D892F150DA76140F210ABD2CBFFCA2C18A27" hashAlgorithm="SHA256" allowUntrustedRoot="false" />
      <certificate fingerprint="566A31882BE208BE4422F7CFD66ED09F5D4524A5994F50CCC8B05EC0528C1353" hashAlgorithm="SHA256" allowUntrustedRoot="false" />
      <certificate fingerprint="9A1B131BEE0605433056A4EA3815478A8E177961A968C6C0027C1093D1FEB630" hashAlgorithm="SHA256" allowUntrustedRoot="false" />
    </author>
  </trustedSigners>
</configuration>

En un nuget.config real, este bloque convive con las demás secciones de configuración, como packageSources o packageSourceMapping, cuando el proyecto las necesita.

Primero, descubre qué configuración usa CI

NuGet puede leer archivos de configuración con distintos alcances: solución, usuario, máquina, contenedor o parámetros explícitos del comando. Por eso revisar el archivo junto al .csproj no siempre revela la política efectiva del pipeline.

Empieza registrando el SDK del runner:

dotnet --info

Después localiza configuraciones y scripts que puedan imponer la política. En un repositorio donde rg esté disponible, una búsqueda inicial puede ser:

rg -n "signatureValidationMode|trustedSigners|dotnet nuget verify" -g "nuget.config" -g "*.yml" -g "*.yaml" -g "*.ps1" -g "*.sh" .

Repite la inspección dentro de la imagen o del agente que ejecuta el restore. La referencia de nuget.config de Microsoft Learn confirma que signatureValidationMode=require exige que la firma coincida con un firmante de confianza; también describe la jerarquía de archivos y que una entrada de autor puede contener varias huellas.

La migración mínima, con una advertencia de sintaxis

La documentación actual de dotnet nuget trust, aplicable al SDK .NET 6 y posteriores, separa estas operaciones:

  • trust list inspecciona los firmantes y sus certificados.
  • trust certificate <NAME> <FINGERPRINT> añade una huella a un firmante existente o crea un autor si no existe.
  • trust author <NAME> <PACKAGE_PATH> obtiene la identidad desde un archivo .nupkg firmado.

Por tanto, después de confirmar que el SDK instalado documenta el subcomando, la forma respaldada para añadir la huella directa es:

dotnet nuget trust list --configfile .\nuget.config
dotnet nuget trust certificate Microsoft 9A1B131BEE0605433056A4EA3815478A8E177961A968C6C0027C1093D1FEB630 --algorithm SHA256 --configfile .\nuget.config

El aviso del blog de Microsoft muestra, en cambio, dotnet nuget trust author Microsoft <huella> --algorithm SHA256. Esa forma no coincide con la sintaxis de Learn: en la referencia actual, author espera una ruta de paquete, no una huella, mientras certificate espera la huella. Puede ser una diferencia entre versiones o un error en el ejemplo del aviso. Comprueba dotnet nuget trust --help con el SDK que usa tu runner y, si la sintaxis no está disponible, edita el nodo trustedSigners mediante una revisión controlada.

La opción --allow-untrusted-root no es una solución para esta transición. La referencia la marca como no recomendada porque relaja la validación de la cadena de certificados. La entrada generada para un certificado de Microsoft debe mantener allowUntrustedRoot="false", salvo que exista una decisión de seguridad independiente, documentada y aprobada.

Verifica un paquete y luego prueba el restore

La referencia oficial de dotnet nuget verify admite varias opciones --certificate-fingerprint; cada una añade una huella SHA-256 aceptada. Para probar un paquete representativo, conserva todos los certificados que tu política autoriza:

dotnet nuget verify .\paquete.nupkg `
  --certificate-fingerprint 3F9001EA83C560D712C24CF213C3D312CB3BFF51EE89435D3430BD06B5D0EECE `
  --certificate-fingerprint AA12DA22A49BCE7D5C1AE64CC1F3D892F150DA76140F210ABD2CBFFCA2C18A27 `
  --certificate-fingerprint 566A31882BE208BE4422F7CFD66ED09F5D4524A5994F50CCC8B05EC0528C1353 `
  --certificate-fingerprint 9A1B131BEE0605433056A4EA3815478A8E177961A968C6C0027C1093D1FEB630 `
  --configfile .\nuget.config

En Bash, cambia la continuación con acento grave por \ o escribe el comando en una sola línea. No confundas la huella del certificado con el hash de contenido del paquete: son controles distintos. dotnet nuget verify muestra el hash de contenido del paquete en .NET 10 y posteriores; la política de firmantes sigue comparando el certificado de firma.

Finalmente ejecuta el restore con el mismo archivo y el mismo SDK que CI:

dotnet restore --configfile .\nuget.config

Prueba primero en un runner aislado o en staging. Guarda como artefacto dotnet --info, el archivo de configuración efectivo (sin secretos), el paquete de prueba y la salida de verificación. Si el pipeline usa un contenedor, registra también la etiqueta o el digest de la imagen. Así una futura incidencia puede relacionarse con un SDK y una política concretos.

Cómo leer un NU3034

El error NU3034 aparece cuando el modo require no encuentra un firmante permitido: puede faltar la lista o la huella del paquete no coincidir con ninguna entrada. No lo trates como un problema de red sin más.

Comprueba, en este orden:

  1. Que la huella se copió completa, sin espacios ni caracteres omitidos, y tiene 64 dígitos hexadecimales para SHA-256.
  2. Que el runner abrió el nuget.config esperado y no otro de usuario, máquina o imagen base.
  3. Si se valida la firma de autor de Microsoft, que el paquete corresponde a <author> y que la entrada contiene la huella esperada. Si el paquete está firmado por un repositorio, revisa <repository>, su serviceIndex y los certificados declarados por ese repositorio; NU3034 también cubre una firma de repositorio ausente o no permitida.
  4. Que las huellas históricas siguen presentes si el paquete fue publicado antes del cambio.
  5. Que la cadena de certificados es confiable en el sistema y que no se introdujo allowUntrustedRoot para ocultar otro problema.

Solo después revisa feed, cachés y conectividad. Cambiar signatureValidationMode de require a accept, borrar trustedSigners o permitir una raíz no confiable silencia el síntoma, pero elimina el control que originó la alerta.

Una huella no sustituye la seguridad de la cadena de suministro

Una firma de autor permite relacionar el paquete con un certificado aceptado por tu política. No demuestra que el código sea benigno, que no tenga una vulnerabilidad ni que sus dependencias sean adecuadas para producción. Mantén además:

  • lock files y revisiones de cambios de dependencias;
  • packageSourceMapping cuando necesites limitar qué origen puede resolver cada paquete;
  • hash de contenido o revisión de artefactos cuando tu proceso lo requiera;
  • feeds administrados, permisos mínimos y protección de credenciales del pipeline;
  • análisis de vulnerabilidades, revisión de dependencias y pruebas reproducibles.

La actualización correcta es aditiva y comprobable: descubre la política efectiva, conserva las huellas históricas, agrega la nueva, valida un paquete y prueba el restore en el entorno real. No hace falta abrir la confianza a cualquier paquete para superar la transición.

Fuentes primarias

Comentarios

Cargando…