Signtool允许我签署代码,但Set-AuthenticodeSignature说"证书不适合代码签名"

Sco*_*ain 10 powershell code-signing signtool

我有一个自签名代码签名证书(使用此答案中的说明制作),当我使用时它可以正常工作signtool.exe.但是,如果我尝试使用Powershell进行签名,则会失败.

用signtool签名

C:\>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
Run Code Online (Sandbox Code Playgroud)

登录Powershell

PS C:\> $cert = @(Get-Childitem cert:\CurrentUser\My | Where-Object -FilterScript {$_.Subject -eq 'CN=VetWeb'})[0]
PS C:\> 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

PS C:\> $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
Run Code Online (Sandbox Code Playgroud)

为什么我可以使用signtool.exe进行签名,但不能使用Powershell进行签名?


PS运行Get-Childitem cert:\CurrentUser\My -CodeSigningCert没有返回任何结果.

Arp*_*han 9

我有同样的问题,我想出的答案是我必须创建两个证书.首先,使用受信任的根证书颁发机构

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
Run Code Online (Sandbox Code Playgroud)

然后从上述证书颁发机构使用的个人证书

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
Run Code Online (Sandbox Code Playgroud)

创建完成后,使用

$cert = @(Get-ChildItem cert:\CurrentUser\My -CodeSigning)[0]
Run Code Online (Sandbox Code Playgroud)

用于签名(假设您只有一个代码签名证书).例如,如果脚本的名称是xyz.ps1,请在PowerShell中使用此命令

Set-AuthenticodeSignature path/to/xyz.ps1 $cert
Run Code Online (Sandbox Code Playgroud)


JW0*_*914 5

\n

问题是签名证书格式错误并且缺少正确的 KU 和 EKU。

\n

openssl要解决此问题,请使用下面链接的内容创建自签名 CA openssl.cnf、由自签名 CA 签名的代码签名 ICA,以及最后由 ICA 签名的代码签名证书

\n
\n

预构建openssl.cnf包含从第 430 行开始所需的所有信息和命令:

\n
    \n
  1. 先决条件: \n
      \n
    • Windows安装OpenVPN(包括openssl-utils
      (添加到系统PATH:)%ProgramFiles%\\OpenVPN\\bin
    • \n
    • BSD/Linux安装openssl|| openssl-utils|| 编译
    • \n
    \n
  2. \n
  3. 创建 CA: \n
    # CA key should have a secure passphrase of at least 20 characters, containing \n# at least 2 uppercase, 2 lowercase, 2 numbers, and 2 symbols\n\n\n# PreReqs: Create files crlnumber, index, rand, & serial\n  mkdir cert crl \n  echo 01 > crl\\crlnumber ; echo > index ; echo > rand ; echo 00 > serial\n\n\n# Create CA:\n  openssl req -x509 -new -sha512 -days 3650 -newkey rsa:4096 -keyout "CA.key.pem" -out "CA.crt.pem" -config "openssl.cnf" -extensions v3_ca\n
    Run Code Online (Sandbox Code Playgroud)\n
  4. \n
  5. 创建 ICA: \n
    # ICA key should have a secure passphrase of at least 20 characters, containing \n# at least 2 uppercase, 2 lowercase, 2 numbers, and 2 symbols\n\n\n# Request:\n  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\n\n# Sign:\n  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\n\n  # Create Concatenated CA - ICA Cert Chain:\n    # Windows:\n      cmd /c type "code-signing-ICA.crt.pem" "CA.crt.pem" > "code-signing-ICA-Chain.crt.pem"\n\n    # BSD/Linux:\n      cat "code-signing-ICA.crt.pem" "CA.crt.pem" > "code-signing-ICA-Chain.crt.pem"\n
    Run Code Online (Sandbox Code Playgroud)\n
  6. \n
  7. 创建签名证书: \n
    # Request:\n  openssl req -out "code-signing.csr" -new -days 3650 -sha512 -newkey rsa:2048 -keyout "code-signing.key.pem" -config "openssl.cnf" -extensions v3_codesign\n\n# Sign:\n  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\n\n# Export:\n  openssl pkcs12 -export -out "code-signing.p12" -inkey "code-signing.key.pem" -in "code-signing.crt.pem" -certfile "code-signing-ICA-chain.crt.pem"\n
    Run Code Online (Sandbox Code Playgroud)\n
  8. \n
\n
\n
\n

OpenSSL KU 和 EKU

\n

代码签名证书应具有以下设置:

\n
    \n
  • \n
    keyUsage  = critical, nonRepudiation, digitalSignature\n
    Run Code Online (Sandbox Code Playgroud)\n
      \n
    • nonRepudiation
      证书可用于如上所述对数据进行签名,但证书公钥可用于提供不可否认服务
      (防止签名实体错误地否认某些操作)
    • \n
    • digitalSignature
      证书可用于应用数字签名
      (用于实体认证和数据源完整性认证)

    • \n
    \n
  • \n
  • \n
    extendedKeyUsage  = critical, codeSigning, msCodeInd, msCodeCom, mcCTLSign, timeStamping\n
    Run Code Online (Sandbox Code Playgroud)\n
      \n
    • codeSigning
      代码签名
    • \n
    • msCodeInd
      微软个人代码签名(authenticode)
    • \n
    • msCodeCom:
      微软商业代码签名(authenticode)
    • \n
    • mcCTLSign:
      微软信任列表签名
    • \n
    • timeStamping
      可信时间戳

    • \n
    \n
  • \n
\n
\n

SignTool

\n

先决条件:

\n
    \n
  1. 安装Windows SDK
  2. \n
  3. WinKey+R \xe2\x86\x92 sysdm.cpl\xe2\x86\x92 确定
    高级\xe2\x86\x92环境变量... \xe2\x86\x92系统变量\xe2\x86\x92路径\xe2\x86\x92编辑.. 。
  4. \n
  5. 添加到路径:%ProgramFiles(x86)%\\Windows Kits\\10\\bin\\10.0.15063.0\\x64 \n
      \n
    • 确保\\10\\bin\\10.0.15063.0\\x64反映您的 Windows 版本的正确路径

    • \n
    \n
  6. \n
\n
# Establish $TS variable:\n  Set-Variable -Name TS -Value "http://sha256timestamp.ws.symantec.com/sha256/timestamp" -Scope "Global"\n\n# Sign:\n  SignTool sign /s "MY" /fd "SHA256" /ph /td "SHA256" /tr $TS "Path\\to\\File"\n
Run Code Online (Sandbox Code Playgroud)\n
    \n
  • sign:
    使用嵌入签名对文件进行签名
  • \n
  • /s<name>
    指定搜索证书时打开的Store(默认:MY Store)
  • \n
  • /fd
    指定用于创建文件签名的文件摘要算法(默认值:SHA1)
  • \n
  • /ph:
    如果支持,为可执行文件生成页面哈希值
  • \n
  • /td<alg>: 与或 一起
    使用/tr/tseal请求 RFC3161 时间戳服务器使用的摘要算法
  • \n
  • /tr<URL>
    指定 RFC3161 时间戳服务器的 URL (如果时间戳失败会生成警告) \n
      \n
    • 如果未指定/tr/t,则签名文件将不会带有时间戳

    • \n
    \n
  • \n
\n
\n

电源外壳

\n
# Establish $cert variable:\n  $cert = Get-PfxCertificate -FilePath "Path\\to\\Signing\\Cert"\n\n# Establish $TS variable (if not already set above):\n  Set-Variable -Name TS -Value "http://sha256timestamp.ws.symantec.com/sha256/timestamp" -Scope "Global"\n\n# Sign:\n  Set-AuthenticodeSignature -HashAlgorithm "sha256" -IncludeChain "all" -FilePath "File"  -Certificate $cert -TimestampServer $TS\n
Run Code Online (Sandbox Code Playgroud)\n
    \n
  • Set-AuthenticodeSignature
    将 Authenticode 签名添加到 PowerShell 脚本或其他文件中
  • \n
  • -HashAlgorithm
    指定用于计算数字签名的哈希算法
    (PowerShell 2:sha1 || PowerShell 3+:sha256)
  • \n
  • -IncludeChain <String>
    确定信任链中的哪些证书包含在数字签名中(默认:NotRoot;可接受的值:\n
      \n
    • Signer仅包含签名者的证书
    • \n
    • NotRoot包括证书链中的所有证书,根权限除外
    • \n
    • All包含证书链中的所有证书
    • \n
    \n
  • \n
  • -Certificate <X509Certificate>
    将用于签署脚本或文件的证书;输入一个变量,该变量存储表示证书的对象或获取证书的表达式\n
      \n
    • 要查找证书,请使用Get-PfxCertificateGet-ChildItem在证书 [ Cert:] 驱动器中;如果证书无效或没有codeSigning权限,命令将失败
    • \n
    \n
  • \n
\n