How do I create a self-signed certificate for code signing using tools from the Windows SDK?
How do I create a self-signed certificate for code signing using tools from the Windows SDK?
If you are using the following Windows versions or later: Windows Server 2012, Windows Server 2012 R2, or Windows 8.1 then MakeCert is now deprecated, and Microsoft recommends using the PowerShell Cmdlet New-SelfSignedCertificate.
If you're using an older version such as Windows 7, you'll need to stick with MakeCert or another solution. Some people suggest the Public Key Infrastructure Powershell (PSPKI) Module.
While you can create a self-signed code-signing certificate (SPC - Software Publisher Certificate) in one go, I prefer to do the following:
makecert -r -pe -n "CN=My CA" -ss CA -sr CurrentUser ^
-a sha256 -cy authority -sky signature -sv MyCA.pvk MyCA.cer
(^ = allow batch command-line to wrap line)
This creates a self-signed (-r) certificate, with an exportable private key (-pe). It's named "My CA", and should be put in the CA store for the current user. We're using the SHA-256 algorithm. The key is meant for signing (-sky).
The private key should be stored in the MyCA.pvk file, and the certificate in the MyCA.cer file.
Because there's no point in having a CA certificate if you don't trust it, you'll need to import it into the Windows certificate store. You can use the Certificates MMC snapin, but from the command line:
certutil -user -addstore Root MyCA.cer
makecert -pe -n "CN=My SPC" -a sha256 -cy end ^
-sky signature ^
-ic MyCA.cer -iv MyCA.pvk ^
-sv MySPC.pvk MySPC.cer
It is pretty much the same as above, but we're providing an issuer key and certificate (the -ic and -iv switches).
We'll also want to convert the certificate and key into a PFX file:
pvk2pfx -pvk MySPC.pvk -spc MySPC.cer -pfx MySPC.pfx
If you are using a password please use the below
pvk2pfx -pvk MySPC.pvk -spc MySPC.cer -pfx MySPC.pfx -po fess
If you want to protect the PFX file, add the -po switch, otherwise PVK2PFX creates a PFX file with no passphrase.
signtool sign /v /f MySPC.pfx ^
/t http://timestamp.url MyExecutable.exe
(See why timestamps may matter)
If you import the PFX file into the certificate store (you can use PVKIMPRT or the MMC snapin), you can sign code as follows:
signtool sign /v /n "Me" /s SPC ^
/t http://timestamp.url MyExecutable.exe
Some possible timestamp URLs for signtool /t are:
http://timestamp.verisign.com/scripts/timstamp.dllhttp://timestamp.globalsign.com/scripts/timstamp.dllhttp://timestamp.comodoca.com/authenticodehttp://timestamp.digicert.comMakeCert is available from the Visual Studio Command Prompt. Visual Studio 2015 does have it, and it can be launched from the Start Menu in Windows 7 under "Developer Command Prompt for VS 2015" or "VS2015 x64 Native Tools Command Prompt" (probably all of them in the same folder).
As stated in the answer, in order to use a non deprecated way to sign your own script, one should use New-SelfSignedCertificate.
New-SelfSignedCertificate -DnsName email@yourdomain.com -Type CodeSigning -CertStoreLocation cert:\CurrentUser\My
Export-Certificate -Cert (Get-ChildItem Cert:\CurrentUser\My -CodeSigningCert)[0] -FilePath code_signing.crt
The [0] will make this work for cases when you have more than one certificate... Obviously make the index match the certificate you want to use... or use a way to filtrate (by thumprint or issuer).
Import-Certificate -FilePath .\code_signing.crt -Cert Cert:\CurrentUser\TrustedPublisher
Import-Certificate -FilePath .\code_signing.crt -Cert Cert:\CurrentUser\Root
Set-AuthenticodeSignature .\script.ps1 -Certificate (Get-ChildItem Cert:\CurrentUser\My -CodeSigningCert)
Obviously once you have setup the key, you can simply sign any other scripts with it.
You can get more detailed information and some troubleshooting help in this article.
It's fairly easy using the New-SelfSignedCertificate command in Powershell. Open powershell and run these 3 commands.
Create certificate:
$cert = New-SelfSignedCertificate -DnsName www.yourwebsite.com -Type CodeSigning -CertStoreLocation Cert:\CurrentUser\Myset the password for it:
$CertPassword = ConvertTo-SecureString -String "my_passowrd" -Force -AsPlainTextExport it:
Export-PfxCertificate -Cert "cert:\CurrentUser\My$($cert.Thumbprint)" -FilePath "d:\selfsigncert.pfx" -Password $CertPassword
Your certificate selfsigncert.pfx will be located @ D:/
Optional step: You would also require to add certificate password to system environment variables. do so by entering below in cmd: setx CSC_KEY_PASSWORD "my_password"
You can generate one in Visual Studio 2019, in the project properties. In the Driver Signing section, the Test Certificate field has a drop-down. Generating a test certificate is one of the options. The certificate will be in a file with the 'cer' extension typically in the same output directory as your executable or driver.
This post will only answer the "how to sign an EXE file if you have the crtificate" part:
To sign the exe file, I used MS "signtool.exe". For this you will need to download the bloated MS Windows SDK which has a whooping 1GB. FORTUNATELY, you don't have to install it. Just open the ISO and extract "Windows SDK Signing Tools-x86_en-us.msi". It has a merely 400 KB.
Then I built this tiny script file:
prompt $
echo off
cls
copy "my.exe" "my.bak.exe"
"c:\Program Files (x86)\Windows Kits\10\bin\10.0.22000.0\x64\signtool.exe" sign /fd SHA256 /f MyCertificate.pfx /p MyPassword My.exe
pause
__