Saltar al contenido

Signtool me permite firmar código, pero Set-AuthenticodeSignature dice que “el certificado no es adecuado para la firma de código”.

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:

  1. Requisito previo:

    • Ventanas: Instale OpenVPN (incluye openssl-utils)
      (agregar al sistema PATH: %ProgramFiles%OpenVPNbin)
    • BSD / Linux: Instalar en pc openssl || openssl-utils || Compilar
  2. 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
    
  3. 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"
    
  4. 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:

  1. Instalar el SDK de Windows
  2. WinKey
    +R
    sysdm.cpl → Aceptar
    AvanzadoVariables de entorno…Variables del sistemaSenderoEditar…
  3. 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
# 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

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 o Get-ChildItem en el certificado [Cert:] conducir; el comando falla si el certificado no es válido o no tiene codeSigning autoridad
¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *