Búsqueda de sitios web

Usando Yubikey para PowerShell CodeSigning


Introducción

Tengo un certificado público de diseño de código emitido por DigiCert. Quiero poder firmar mis scripts de PowerShell en cualquier lugar, por ejemplo, cuando estoy con un cliente, pero es complicado tener que mover el código a donde tengo mi certificado de firma de código solo para firmarlo. He estado experimentando con trabajos de compilación en VSTS, por lo que si reviso un script, un trabajo de compilación lo firmará automáticamente, pero eso requiere acceso a Internet y VSTS.

Yubikey al rescate

Un Yubikey es un pequeño dispositivo USB que se parece un poco a una memoria USB muy delgada. He estado usando Yubikey como segundo factor durante bastante tiempo y ha funcionado muy bien, pero no he pensado en la posibilidad de usarlo para firmar código. Cuando se configura con certificados, funciona como una tarjeta inteligente, conéctela y guardará sus claves privadas. Hace un tiempo restablecí mi clave, le di nuevos códigos PIN y guardé mi certificado de firma en ella. Ahora puedo conectarlo a cualquier computadora y tener mi certificado disponible sin tener que preocuparme por almacenar mi clave privada en algún lugar. Para obtener instrucciones sobre cómo configurar Yubikey, consulte mi publicación sobre cómo configurar Yubikey para la firma de código PowerShell.

Firmar código con mi Yubikey

Una vez que mi certificado se importa a mi Yubikey, puedo insertar la clave en cualquier computadora y habrá un certificado disponible en el almacén de certificados del usuario actual. Enumeremos la tienda y veamos cómo se ve:

Get-ChildItem -Path "cert:\currentuser\my" -CodeSigning

El uso del parámetro -CodeSigning solo funciona cuando la ruta apunta a un almacén de certificados y hará que Get-ChildItem solo devuelva certificados válidos para la firma de código.

A continuación, ¡firmemos algo!

Tengo un módulo llamado DSACL que contiene funciones para configurar ACL en Active Directory. Quiero firmar este módulo antes de publicarlo en la galería. Hay dos formas de firmar un módulo: firmar cada archivo individual y utilizar la firma de catálogo. Voy a utilizar ambos; puede leer más al respecto en la guía de mejores prácticas de publicación para la galería de PowerShell.

Primero necesito una referencia a mi certificado. Si solo tiene un certificado de firma de código en su computadora, puede almacenar el resultado de Get-ChildItem anterior en una variable. Si tienes más de uno, me gusta usar Out-GridView para elegir el que quiero, así:

$Cert = Get-ChildItem -Path 'cert:\currentuser\my' -CodeSigning | Out-GridView -PassThru

Ahora voy a firmar mis archivos de script, esta es la firma que PowerShell validará al cargar el módulo. La firma se realiza con el comando Set-AuthenticodeSignature. Para asegurarme de que mi firma sea válida incluso después de que mi certificado haya caducado, utilizo un servidor de marca de tiempo, esto agregará una marca de tiempo a mi firma y permitirá validar que mi certificado era válido en el momento de la firma. Solo quiero firmar mi módulo y mis archivos de manifiesto, así que uso el siguiente comando y me aseguro de estar en el directorio donde están mis archivos:

Get-ChildItem -Path '*.ps*' | Set-AuthenticodeSignature -Certificate $Cert -TimestampServer 'http://timestamp.digicert.com'

La siguiente parte es crear un archivo de catálogo que contendrá la suma hash de cada archivo, confirmando de esa manera que no se ha cambiado nada. PowerShellGet lo usa cuando instalo mi módulo usando Install-Module. Puedo elegir entre usar la versión 1 o la versión 2 del catálogo. La versión 1 usará SHA1 y la versión 2 usará el algoritmo SHA256. Para compatibilidad con Windows 7 (con el que probablemente tendremos que vivir por un tiempo más), usaré la versión 1. El comando que uso es:

New-FileCatalog -CatalogVersion 1 -CatalogFilePath .\DSACL.cat -Path $PWD.Path

Aquí todavía estoy en el directorio donde están mis archivos a firmar. Esto me permite usar la variable predeterminada $PWD que contiene la ruta de la carpeta actual. Esto creará el archivo DSACL.cat que contendrá los hashes de cada archivo del directorio. Si se modifica, añade o elimina algún archivo, el archivo DSACL.cat dejará de ser válido. Ahora, para asegurarme de que mi archivo de catálogo no haya cambiado, voy a firmarlo usando el siguiente comando:

Set-AuthenticodeSignature -Certificate $Cert -TimestampServer 'http://timestamp.digicert.com' -FilePath .\DSACL.cat

Ahora PowerShell puede validar la firma en cada archivo de PowerShell (el archivo del módulo y el manifiesto del módulo) y PowerShell get puede validar la firma en mi archivo de firma de catálogo, así como la validez de mi archivo de firma de catálogo, siempre y cuando todo esté verificado. , puedo estar seguro de que nadie cambió mi código.

¡Y eso es! ¡Feliz fichaje!

Artículos relacionados