14

I have a self-signed code signing certificate, made with the directions from this answer, that works fine when used with signtool.exe, however if I try to sign using Set-AuthenticodeSignature, it fails.

Why can I sign using signtool, but not using Set-AuthenticodeSignature?

  • signtool:
    Signtool sign /v /n "VetWeb" SetupRDPPermissions.ps1
    
      The following certificate was selected:
        Issued to: VetWeb
        Issued by: VetWeb CA
        Expires:   Sat Dec 31 18:59:59 2039
        SHA1 hash: 84136EBF8D2603C2CD6668C955F920C6C6482EE4
    
      Done Adding Additional Store
      Successfully signed: SetupRDPPermissions.ps1
    
      Number of files successfully Signed: 1
      Number of warnings: 0
    

  • Set-AuthenticodeSignature:
    $cert = @(Get-Childitem cert:\CurrentUser\My | Where-Object -FilterScript {$_.Subject -eq 'CN=VetWeb'})[0]
    
    Set-AuthenticodeSignature SetupRDPPermissions.ps1 $cert
    
      Set-AuthenticodeSignature : Cannot sign code. The specified certificate is not suitable for code signing.
        At line:1 char:26
        + Set-AuthenticodeSignature <<<<  SetupRDPPermissions.ps1 $cert
          + CategoryInfo          : InvalidArgument: (:) [Set-AuthenticodeSignature], PSArgumentException
          + FullyQualifiedErrorId : Argument,Microsoft.PowerShell.Commands.SetAuthenticodeSignatureCommand
    
    • Get-Childitem cert:\CurrentUser\My -CodeSigningCert returns no results

  •  $cert | Format-List *
    
       PSPath             : Microsoft.PowerShell.Security\Certificate::CurrentUser\My\84136EBF8D2603C2CD6668C955F920C6C6482EE4
       PSParentPath       : Microsoft.PowerShell.Security\Certificate::CurrentUser\My
       PSChildName        : 84136EBF8D2603C2CD6668C955F920C6C6482EE4
       PSDrive            : cert
       PSProvider         : Microsoft.PowerShell.Security\Certificate
       PSIsContainer      : False
       Archived           : False
       Extensions         : {System.Security.Cryptography.Oid}
       FriendlyName       :
       IssuerName         : System.Security.Cryptography.X509Certificates.X500DistinguishedName
       NotAfter           : 12/31/2039 5:59:59 PM
       NotBefore          : 6/1/2012 1:49:31 PM
       HasPrivateKey      : True
       PrivateKey         : System.Security.Cryptography.RSACryptoServiceProvider
       PublicKey          : System.Security.Cryptography.X509Certificates.PublicKey
       RawData            : {48, 130, 1, 235...}
       SerialNumber       : CF330347F35AC0B4427AFFA82DB51238
       SubjectName        : System.Security.Cryptography.X509Certificates.X500DistinguishedName
       SignatureAlgorithm : System.Security.Cryptography.Oid
       Thumbprint         : 84136EBF8D2603C2CD6668C955F920C6C6482EE4
       Version            : 3
       Handle             : 479608336
       Issuer             : CN=VetWeb CA
       Subject            : CN=VetWeb
    
4

3 に答える 3

11

私は同じ問題を抱えていましたが、私が見つけた答えは、2 つの証明書を作成する必要があるということでした。まず、信頼されたルート認証局

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

そして、上記の認証局からの個人証明書を使用して

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

これらが作成されたら、使用します

$cert = @(Get-ChildItem cert:\CurrentUser\My -CodeSigning)[0]

署名用 (コード署名証明書が 1 つしかない場合)。たとえば、スクリプトの名前が xyz.ps1 の場合、PowerShell で次のコマンドを使用します。

Set-AuthenticodeSignature path/to/xyz.ps1 $cert
于 2013-09-03T03:42:41.723 に答える
4

get-help によると-CodeSigningCert、証明書プロバイダーからの証明書の動的パラメーターは、コード署名権限を持つ証明書のみを取得します。

なぜsigntool署名できるのに署名できないのかSet-AuthenticodeSignature、説明はおそらくコード署名の概要Microsoftドキュメントにあります。

これが私のバージョンの認証局です:

# 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

これが私のバージョンの開発証明書です:

# 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
于 2012-06-07T20:18:11.143 に答える
3

問題は、署名証明書の形式が正しくなく、正しい KU と EKU がないことです。

openssl解決するには、以下のリンクを使用して自己署名 CA を作成し、自己署名 CAopenssl.cnfによって署名されたコード署名 ICA、最後に ICA によって署名されたコード署名証明書を作成します。


openssl.cnf430 行目以降に必要なすべての情報とコマンドが事前に組み込まれています。

  1. 前提条件:
    • Windows : OpenVPNをインストール(含むopenssl-utils)
      (システムに追加PATH: %ProgramFiles%\OpenVPN\bin)
    • BSD/Linux :インストールopenssl|| openssl-utils|| コンパイル
  2. 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 > crl\crlnumber ; 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. 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. 署名証明書の作成:
    # 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 と EKU

コード署名証明書には、次のセットが必要です。

  • keyUsage  = critical, nonRepudiation, digitalSignature
    
    • nonRepudiation:
      証明書は上記のようにデータに署名するために使用できますが、証明書の公開鍵は否認防止サービスを提供するために使用できます
      (署名エンティティが何らかのアクションを誤って拒否するのを防ぎます)。
    • digitalSignature:
      証明書を使用してデジタル署名を適用することができます
      (完全性を備えたエンティティ認証とデータ オリジン認証に使用されます)

  • extendedKeyUsage  = critical, codeSigning, msCodeInd, msCodeCom, mcCTLSign, timeStamping
    
    • codeSigning:
      コード署名
    • msCodeInd:
      Microsoft 個別コード署名 (authenticode)
    • msCodeCom:
      Microsoft 商用コード署名 (authenticode)
    • mcCTLSign:
      Microsoft 信頼リストの署名
    • timeStamping:
      信頼できるタイムスタンプ


SignTool

前提条件:

  1. Windows SDKをインストールする
  2. WinKey+Rsysdm.cpl→ OK
    詳細設定環境変数...システム変数パス編集...
  3. パスに追加:%ProgramFiles(x86)%\Windows Kits\10\bin\10.0.15063.0\x64
    • \10\bin\10.0.15063.0\x64Windows バージョンの適切なパスが反映されていることを確認します

# 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 "Path\to\File"
  • sign:
    埋め込まれた署名を使用してファイルに署名します
  • /s<name>:
    証明書を検索するときに開くストアを指定します(デフォルト:MYストア)
  • /fd:
    ファイル署名の作成に使用するファイル ダイジェスト アルゴリズムを指定します(デフォルト: SHA1)
  • /ph:
    サポートされている場合、実行可能ファイルのページ ハッシュを生成します
  • /td<alg>: RFC3161 タイムスタンプ サーバーで使用されるダイジェスト アルゴリズム
    と共に、/trまたはダイジェスト アルゴリズムを要求するために使用されます。/tseal
  • /tr<URL>:
    RFC3161 タイムスタンプ サーバーの URL を指定します(タイムスタンプに失敗すると警告が生成されます)
    • /trまたはが指定されていない場合/t、署名されたファイルにはタイムスタンプが付けられません


パワーシェル

# Establish $cert variable:
  $cert = Get-PfxCertificate -FilePath "Path\to\Signing\Cert"

# 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:
    Authenticode 署名を PowerShell スクリプトまたはその他のファイルに追加します
  • -HashAlgorithm:
    デジタル署名の計算に使用されるハッシュ アルゴリズムを指定します
    (PowerShell 2: sha1 || PowerShell 3+: sha256)
  • -IncludeChain <String>:
    信頼チェーン内のどの証明書がデジタル署名に含まれるかを決定します(デフォルト: NotRoot) ; 許容値:
    • Signer:署名者の証明書のみが含まれます
    • NotRoot:ルート認証局を除く、証明書チェーン内のすべての証明書が含まれます
    • All:証明書チェーン内のすべての証明書を含みます
  • -Certificate <X509Certificate>:
    スクリプトまたはファイルの署名に使用される証明書。証明書を表すオブジェクトを格納する変数、または証明書を取得する式を入力します
    • 証明書を見つけるには、Certificate [ ] ドライブでGet-PfxCertificateまたはを使用します。証明書が有効でないか権限がない場合、コマンドは失敗しますGet-ChildItemCert:codeSigning
于 2017-10-12T15:52:16.080 に答える