ccnokes ccnokes - 3 months ago 207
PowerShell Question

Unable to code sign with Windows signtool

I'm trying to understand code signing of executable files on Windows by creating my own self-signed certificate and successfully signing a file. The signtool is throwing an error and saying that "No certificates were found that met all the given criteria."

What am I doing wrong?

Here's what I've done:

Following some instructions from MS and other blogs, I create a self signed certificate like so:

New-SelfSignedCertificate -certstorelocation Cert:\LocalMachine\my -dnsname cameronnokes.com

$pwd = ConvertTo-SecureString -String "password" -Force -AsPlainText

Export-PfxCertificate -cert Cert:\LocalMachine\my\C7A94086D80A42151551A9FCCEACBC0B4A9ABA1A -FilePath 'C:\Users\Cameron Nokes\selfcert.pfx' -Password $pwd

Get-ChildItem -Recurse Cert:\LocalMachine\my


That last Get-ChildItem command displays the thumbprint and subject and looks like I'd expect it to.

Now, in cmd, I run:

signtool.exe sign /f selfcert.pfx /p password /debug test.ps1


The following certificates were considered:
Issued to: cameronnokes.com
Issued by: cameronnokes.com
Expires: Sat Aug 05 12:37:28 2017
SHA1 hash: C7A94086D80A42151551A9FCCEACBC0B4A9ABA1A

After EKU filter, 0 certs were left.
After expiry filter, 0 certs were left.
After Private Key filter, 0 certs were left.
SignTool Error: No certificates were found that met all the given criteria.

Answer

Took a moment to remember the quirks of certreq, it's there by default and you can use it to generate a key for you.

Make this request.inf:

[NewRequest]
Subject = "CN=cameronnokes.com"
Exportable = TRUE
KeyLength = 2048
KeySpec = 1
KeyUsage = 0xA0
RequestType = Cert

[EnhancedKeyUsageExtension]
OID = 1.3.6.1.5.5.7.3.3 ; Code signing

Then run this command:

certreq -new request.inf nothing.csr

You can then delete both request.inf and nothing.csr. At this point you have a self-signed code-signing certificate in your personal store.

$Certificate = Get-ChildItem cert:\CurrentUser\My |
    Where-Object { $_.EnhancedKeyUsageList.FriendlyName -eq 'Code Signing' -and $_.NotAfter -gt (Get-Date) } |
    Sort-Object NotAfter |
    Select-Object -Last 1

You wouldn't really want to be so vague when choosing the certificate, it's like this for the example only.

Finally, sign a ps1:

Set-AuthenticodeSignature test.ps1 -Certificate $Certificate

Simple, right?

Chris

Comments