Solución:
Tuve el mismo problema y la respuesta que descubrí fue que tenía que crear dos certificados. Primero, una autoridad de certificación raíz de confianza que utilice
makecert -n "CN=PowerShell Local Certificate Root" -a sha1 -eku 1.3.6.1.5.5.7.3.3 -r -sv root.pvk root.cer -ss Root -sr localMachine
Y luego un certificado personal de la autoridad de certificación anterior usando
makecert -pe -n "CN=PowerShell User" -ss MY -a sha1 -eku 1.3.6.1.5.5.7.3.3 -iv root.pvk -ic root.cer
Una vez creados, utilice
$cert = @(Get-ChildItem cert:CurrentUserMy -CodeSigning)[0]
para firmar (asumiendo que solo tiene un certificado de firma de código). Por ejemplo, si el nombre del script es xyz.ps1, use este comando en PowerShell
Set-AuthenticodeSignature path/to/xyz.ps1 $cert
Según certificado get-help -CodeSigningCert
El parámetro dinámico del proveedor de certificados obtiene solo los certificados con autoridad de firma de código.
Ahora por qué signtool
puede firmar y no Set-AuthenticodeSignature
, la explicación tal vez se encuentre en el documento Introducción a la firma de código de Microsoft.
Aquí está mi versión de generación de autoridad de certificación:
# Gen-CACert.ps1
clear-host
$scriptBlock = {.Makecert -n `"CN=PowerShell Authorite de certification`" <# Sujet du certificat (conforme à la norme X50 #>`
-a sha1 <# Algorithme utilisé #>`
-eku 1.3.6.1.5.5.7.3.3 <# Option du certificat (signature de code) #>`
-r <# Certificat auto signé #>`
<# -ss `"$($args[0])`" Dossier de stockage du certificat #>`
-ss `"root`" <# Dossier de stockage du certificat #>`
-sr localMachine <# Magasin de stockage localmachine ou currentuser (defaut) #>`
-sv `"$($args[0]).pvk`" <# Nom du fichier contenant la clef privée #>`
`"$($args[0]).cer`"} <# Nom du fichier certificat #>
$PoshCARoot = "PoshCARoot"
Invoke-Command -ScriptBlock $scriptBlock -ArgumentList $PoshCARoot
Aquí está mi versión de generación de certificado de desarrollo:
# Gen-DevCert.ps1
clear-host
$scriptBlock = {.Makecert -pe <# La clef privée est exportable #>`
-n `"CN=PowerShell Dev Team`" <# Sujet du certificat (conforme à la norme X509 #>`
-a sha1 <# Algorithme utilisé #>`
-eku 1.3.6.1.5.5.7.3.3 <# Option du certificat (signature de code) #>`
-ss `"My`" <# Dossier de stockage du certificat #>`
-sr currentuser <# Magasin de stockage localmachine ou currentuser (defaut) #>`
-iv `"$($args[0]).pvk`" <# Clef privée de l'autorité #>`
-ic `"$($args[0]).cer`" <# Certificat de l'autorité #>`
`"$($args[1]).cer`"} <# Nom du fichier certificat #>
$PoshCARoot = "PoshCARoot"
$PoshDevTeam = "PoshDevTeam"
Invoke-Command -ScriptBlock $scriptBlock -ArgumentList $PoshCARoot,$PoshDevTeam
El problema es que el certificado de firma tiene un formato incorrecto y faltan las KU y EKU correctas.
Para resolverlo, cree una CA autofirmada utilizando openssl
y el openssl.cnf
enlazado a continuación, un ICA de firma de código firmado por la CA autofirmada y, finalmente, un certificado de firma de código firmado por ICA
Preconstruido openssl.cnf
contiene toda la información y los comandos necesarios a partir de la línea 430:
-
Requisito previo:
-
Ventanas: Instale OpenVPN (incluye
openssl-utils
)
(agregar al sistemaPATH
:%ProgramFiles%OpenVPNbin
) -
BSD / Linux: Instalar en pc
openssl
||openssl-utils
|| Compilar
-
Ventanas: Instale OpenVPN (incluye
-
Crear CA:
# CA key should have a secure passphrase of at least 20 characters, containing # at least 2 uppercase, 2 lowercase, 2 numbers, and 2 symbols # PreReqs: Create files crlnumber, index, rand, & serial mkdir cert crl echo 01 > crlcrlnumber ; echo > index ; echo > rand ; echo 00 > serial # Create CA: openssl req -x509 -new -sha512 -days 3650 -newkey rsa:4096 -keyout "CA.key.pem" -out "CA.crt.pem" -config "openssl.cnf" -extensions v3_ca
-
Crear ICA:
# ICA key should have a secure passphrase of at least 20 characters, containing # at least 2 uppercase, 2 lowercase, 2 numbers, and 2 symbols # Request: openssl req -out "code-signing-ICA.csr" -new -days 3650 -sha512 -newkey rsa:4096 -keyout "code-signing-ICA.key" -config "openssl.cnf" -extensions v3_signing_ica # Sign: openssl x509 -req -sha512 -days 3650 -in "code-signing-ICA.csr" -CA "CA.crt.pem" -CAkey "CA.key.pem" -CAserial "serial" -out "code-signing-ICA.crt.pem" -extfile "openssl.cnf" -extensions v3_signing_ica # Create Concatenated CA - ICA Cert Chain: # Windows: cmd /c type "code-signing-ICA.crt.pem" "CA.crt.pem" > "code-signing-ICA-Chain.crt.pem" # BSD/Linux: cat "code-signing-ICA.crt.pem" "CA.crt.pem" > "code-signing-ICA-Chain.crt.pem"
-
Crear certificado de firma:
# Request: openssl req -out "code-signing.csr" -new -days 3650 -sha512 -newkey rsa:2048 -keyout "code-signing.key.pem" -config "openssl.cnf" -extensions v3_codesign # Sign: openssl x509 -req -sha512 -days 3650 -in "code-signing.csr" -CA "code-signing-ICA-chain.crt.pem" -CAkey "code-signing-ICA.key.pem" -CAserial "serial" -out "code-signing.crt.pem" -extfile "openssl.cnf" -extensions v3_codesign # Export: openssl pkcs12 -export -out "code-signing.p12" -inkey "code-signing.key.pem" -in "code-signing.crt.pem" -certfile "code-signing-ICA-chain.crt.pem"
OpenSSL KU y EKU
Los certificados de firma de código deben tener el siguiente conjunto:
-
keyUsage = critical, nonRepudiation, digitalSignature
-
nonRepudiation
:
El certificado se puede usar para firmar datos como se indicó anteriormente, pero la clave pública del certificado se puede usar para proporcionar servicios de no repudio
(Evita que la entidad firmante niegue falsamente alguna acción) -
digitalSignature
:
El certificado se puede utilizar para aplicar una firma digital.
(Utilizado para autenticación de entidad y autenticación de origen de datos con integridad)
-
-
extendedKeyUsage = critical, codeSigning, msCodeInd, msCodeCom, mcCTLSign, timeStamping
-
codeSigning
:
Firma de código -
msCodeInd
:
Firma de código individual de Microsoft (authenticode) -
msCodeCom
:
Firma de código comercial de Microsoft (authenticode) -
mcCTLSign
:
Firma de listas de confianza de Microsoft -
timeStamping
:
Sellado de tiempo de confianza
-
SignTool
Requisitos previos:
- Instalar el SDK de Windows
-
sysdm.cpl
→ Aceptar
Avanzado → Variables de entorno… → Variables del sistema → Sendero → Editar… - Agregar a RUTA:
%ProgramFiles(x86)%Windows Kits10bin10.0.15063.0x64
- Garantizar
10bin10.0.15063.0x64
refleja la ruta adecuada para su versión de Windows
- Garantizar
# Establish $TS variable:
Set-Variable -Name TS -Value "http://sha256timestamp.ws.symantec.com/sha256/timestamp" -Scope "Global"
# Sign:
SignTool sign /s "MY" /fd "SHA256" /ph /td "SHA256" /tr $TS "PathtoFile"
-
sign
:
Firmar archivos con una firma incrustada -
/s
<name>
:
Especifique la tienda que se abrirá al buscar el certificado (Defecto:MY
Tienda) -
/fd
:
Especifica el algoritmo de resumen de archivos que se utilizará para crear firmas de archivos. (Predeterminado: SHA1) -
/ph
:
Genere hash de página para archivos ejecutables si es compatible -
/td
<alg>
:
Usado con/tr
o/tseal
para solicitar un algoritmo de resumen utilizado por el servidor de marca de tiempo RFC3161 -
/tr
<URL>
:
Especifica la URL del servidor de marca de tiempo RFC3161 (se genera una advertencia si falla la marca de tiempo)- Si
/tr
o/t
no se especifica, el archivo firmado no tendrá marca de tiempo
- Si
Potencia Shell
# Establish $cert variable:
$cert = Get-PfxCertificate -FilePath "PathtoSigningCert"
# Establish $TS variable (if not already set above):
Set-Variable -Name TS -Value "http://sha256timestamp.ws.symantec.com/sha256/timestamp" -Scope "Global"
# Sign:
Set-AuthenticodeSignature -HashAlgorithm "sha256" -IncludeChain "all" -FilePath "File" -Certificate $cert -TimestampServer $TS
-
Set-AuthenticodeSignature
:
Agrega una firma Authenticode a un script de PowerShell u otros archivos -
-HashAlgorithm
:
Especifica el algoritmo hash utilizado para calcular la firma digital.
(PowerShell 2: sha1 || PowerShell 3+: sha256) -
-IncludeChain
<String>
:
Determina qué certificados de la cadena de confianza se incluyen en la firma digital. (defecto:NotRoot
); Valores aceptables:-
Signer
: Incluye solo el certificado del firmante -
NotRoot
: Incluye todos los certificados de la cadena de certificados, excepto la autoridad raíz. -
All
: Incluye todos los certificados en la cadena de certificados
-
-
-Certificate
<X509Certificate>
:
Certificado que se utilizará para firmar el script o archivo; ingrese una variable que almacene un objeto que represente el certificado o una expresión que obtenga el certificado- Para encontrar un certificado, use
Get-PfxCertificate
oGet-ChildItem
en el certificado [Cert:
] conducir; el comando falla si el certificado no es válido o no tienecodeSigning
autoridad
- Para encontrar un certificado, use