Protección de secretos de PowerShell con certificado en Yubikey
Introducción
A veces necesitas almacenar secretos y PowerShell tiene una excelente manera de cifrar texto con los cmdlets *-CMSMessage. Ahora, ¿qué sucede si quiero que otras personas puedan cifrar información sin poder descifrarla nuevamente o si quiero cifrar algo yo mismo y solo poder descifrarlo siguiendo un determinado procedimiento, como verificar la clave de descifrado de un almacenamiento seguro? De cualquier manera, almacenar la clave para descifrarla en un Yubikey es una buena opción.
He escrito algunas publicaciones sobre el uso de Yubikeys con PowerShell antes, puedes encontrarlas aquí:
- Configurar Yubikey para la firma de código PowerShell
- Usando Yubikey para PowerShell CodeSigning
¡Basta, vamos a ello!
Creando un certificado
Para cifrar y descifrar secretos usaremos los cmdlets Protect-CMSMessage y Unprotect-CMSMessage. Para proteger (cifrar) el mensaje necesitamos la clave pública de un certificado y para desproteger (descifrar) el mismo mensaje necesitamos acceso a la clave privada asociada.
En mi ejemplo, simplemente voy a crear un certificado autofirmado; usted podría emitir un certificado similar desde su propia PKI o comprar uno de cualquier proveedor público.
Para comenzar, crearé un archivo inf con algunas configuraciones y usaré certreq para autofirmar un certificado. Por supuesto que hacemos eso con PowerShell. Por supuesto, debes reemplazar el Asunto y el Nombre descriptivo con algo que te convenga.
@'
[Version]
Signature = "$Windows NT$"
[Strings]
szOID_ENHANCED_KEY_USAGE = "2.5.29.37"
szOID_DOCUMENT_ENCRYPTION = "1.3.6.1.4.1.311.80.1"
[NewRequest]
Subject = "[email "
FriendlyName = "Simon CMS"
MachineKeySet = false
KeyLength = 2048
KeySpec = AT_KEYEXCHANGE
HashAlgorithm = Sha256
Exportable = true
RequestType = Cert
KeyUsage = "CERT_KEY_ENCIPHERMENT_KEY_USAGE | CERT_DATA_ENCIPHERMENT_KEY_USAGE"
ValidityPeriod = "Years"
ValidityPeriodUnits = "1"
[Extensions]
%szOID_ENHANCED_KEY_USAGE% = "{text}%szOID_DOCUMENT_ENCRYPTION%"
'@ | Out-File -FilePath MyCert.inf
certreq -new MyCert.inf MyCert.cerEsto debería importar el certificado con clave privada a su almacén de certificados, crear MyCert.cer que contenga la clave pública en el directorio actual y brindarle un resultado similar a:
Installed Certificate:
Serial Number: 54ccbdaf31a10abe4cd700757a71130f
Subject: [email
NotBefore: 10/2/2018 4:21 PM
NotAfter: 10/2/2019 4:31 PM
Thumbprint: 9f6a619dbd6a742fa6cf7af94ace3c42fb7366f8
Friendly Name: Simon CMS
Microsoft Strong Cryptographic Provider
9b7cdfe5f228af229303e2b1ae6d0d5a_266ee505-0860-41b2-be89-617291bb724e
Para asegurarme de realizar un seguimiento, copio la huella digital y la almaceno en una variable. También tomaré una referencia a mi certificado recién creado en la tienda usando Get-Item y exportaré el certificado con su clave privada a un archivo pfx. Al ejecutar Export-PfxCertificate se le solicitará una contraseña; elija una que pueda recordar.
$Thumbprint = '9f6a619dbd6a742fa6cf7af94ace3c42fb7366f8'
$OrgCert = Get-Item -Path "cert:\currentuser\my\$Thumbprint"
Export-PfxCertificate -Cert $OrgCert -FilePath MyCert.pfx -Password (Read-Host -AsSecureString -Prompt 'Password')Pon el certificado en mi Yubikey
A continuación, usaré la herramienta yubico-piv para almacenar el certificado en mi Yubikey. Puede descargar la última versión de Yubico. Estoy usando la versión 1.4.4.
Para no tener que escribir la ruta completa a la herramienta, creo un alias para ella. En mi máquina, el archivo se encuentra en Archivos de programa (x86), es posible que deba ajustar la ruta para que se ajuste a su máquina. Esto importará MyCert.pfx a la ranura 9d de su Yubikey (¡asegúrese de no sobrescribir nada importante!) y le pedirá la contraseña que estableció en el paso anterior.
Set-Alias yubico-piv-tool "C:\Program Files (x86)\Yubico\YubiKey PIV Manager\yubico-piv-tool.exe"
yubico-piv-tool -s 9d -i MyCert.pfx -K PKCS12 -a set-chuid -a import-key -a import-certAhora, cuando el certificado esté almacenado de forma segura en mi Yubikey, puedo eliminar el Ubikey de mi computadora y eliminar el certificado original tanto de mi tienda como del archivo PFX. Después de esto, la clave privada de mi certificado sólo se almacena en mi Yubikey y sin ella no podré descifrar nada.
$OrgCert | Remove-Item
'MyCert.pfx' | Remove-Item¡Eso es todo! ¡Probémoslo!
Para cifrar un mensaje solo necesito la clave pública. Certreq lo almacenó en MyCert.cer y puedo cifrar algo proporcionando la ruta completa al archivo cer al parámetro -To de Protect-CMSMessage. Cuando intento desproteger, aparece el mismo mensaje, me pide que conecte mi tarjeta inteligente (Yubikey).
¡Ve a cifrar algo!