[security] How do I create a self-signed certificate for code signing on Windows?

How do I create a self-signed certificate for code signing using tools from the Windows SDK?

This question is related to security code-signing

The answer is


As of PowerShell 4.0 (Windows 8.1/Server 2012 R2) it is possible to make a certificate in Windows without makecert.exe.

The commands you need are New-SelfSignedCertificate and Export-PfxCertificate.

Instructions are in Creating Self Signed Certificates with PowerShell.


It's fairly easy using the New-SelfSignedCertificate command in Powershell. Open powershell and run these 3 commands.

1) Create certificate:
$cert = New-SelfSignedCertificate -DnsName www.yourwebsite.com -Type CodeSigning -CertStoreLocation Cert:\CurrentUser\My

2) set the password for it:
$CertPassword = ConvertTo-SecureString -String "my_passowrd" -Force –AsPlainText

3) Export 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"


As of PowerShell 4.0 (Windows 8.1/Server 2012 R2) it is possible to make a certificate in Windows without makecert.exe.

The commands you need are New-SelfSignedCertificate and Export-PfxCertificate.

Instructions are in Creating Self Signed Certificates with PowerShell.


As stated in the answer, in order to use a non deprecated way to sign your own script, one should use New-SelfSignedCertificate.

  1. Generate the key:
New-SelfSignedCertificate -DnsName [email protected] -Type CodeSigning -CertStoreLocation cert:\CurrentUser\My
  1. Export the certificate without the private key:
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).

  1. Import it as Trusted Publisher
Import-Certificate -FilePath .\code_signing.crt -Cert Cert:\CurrentUser\TrustedPublisher
  1. Import it as a Root certificate authority.
Import-Certificate -FilePath .\code_signing.crt -Cert Cert:\CurrentUser\Root
  1. Sign the script (assuming here it's named script.ps1, fix the path accordingly).
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.


Roger's answer was very helpful.

I had a little trouble using it, though, and kept getting the red "Windows can't verify the publisher of this driver software" error dialog. The key was to install the test root certificate with

certutil -addstore Root Demo_CA.cer

which Roger's answer didn't quite cover.

Here is a batch file that worked for me (with my .inf file, not included). It shows how to do it all from start to finish, with no GUI tools at all (except for a few password prompts).

REM Demo of signing a printer driver with a self-signed test certificate.
REM Run as administrator (else devcon won't be able to try installing the driver)
REM Use a single 'x' as the password for all certificates for simplicity.

PATH %PATH%;"c:\Program Files\Microsoft SDKs\Windows\v7.1\Bin";"c:\Program Files\Microsoft SDKs\Windows\v7.0\Bin";c:\WinDDK\7600.16385.1\bin\selfsign;c:\WinDDK\7600.16385.1\Tools\devcon\amd64

makecert -r -pe -n "CN=Demo_CA" -ss CA -sr CurrentUser ^
   -a sha256 -cy authority -sky signature ^
   -sv Demo_CA.pvk Demo_CA.cer

makecert -pe -n "CN=Demo_SPC" -a sha256 -cy end ^
   -sky signature ^
   -ic Demo_CA.cer -iv Demo_CA.pvk ^
   -sv Demo_SPC.pvk Demo_SPC.cer

pvk2pfx -pvk Demo_SPC.pvk -spc Demo_SPC.cer ^
   -pfx Demo_SPC.pfx ^
   -po x

inf2cat /drv:driver /os:XP_X86,Vista_X64,Vista_X86,7_X64,7_X86 /v

signtool sign /d "description" /du "www.yoyodyne.com" ^
   /f Demo_SPC.pfx ^
   /p x ^
   /v driver\demoprinter.cat

certutil -addstore Root Demo_CA.cer

rem Needs administrator. If this command works, the driver is properly signed.
devcon install driver\demoprinter.inf LPTENUM\Yoyodyne_IndustriesDemoPrinter_F84F

rem Now uninstall the test driver and certificate.
devcon remove driver\demoprinter.inf LPTENUM\Yoyodyne_IndustriesDemoPrinter_F84F

certutil -delstore Root Demo_CA

Roger's answer was very helpful.

I had a little trouble using it, though, and kept getting the red "Windows can't verify the publisher of this driver software" error dialog. The key was to install the test root certificate with

certutil -addstore Root Demo_CA.cer

which Roger's answer didn't quite cover.

Here is a batch file that worked for me (with my .inf file, not included). It shows how to do it all from start to finish, with no GUI tools at all (except for a few password prompts).

REM Demo of signing a printer driver with a self-signed test certificate.
REM Run as administrator (else devcon won't be able to try installing the driver)
REM Use a single 'x' as the password for all certificates for simplicity.

PATH %PATH%;"c:\Program Files\Microsoft SDKs\Windows\v7.1\Bin";"c:\Program Files\Microsoft SDKs\Windows\v7.0\Bin";c:\WinDDK\7600.16385.1\bin\selfsign;c:\WinDDK\7600.16385.1\Tools\devcon\amd64

makecert -r -pe -n "CN=Demo_CA" -ss CA -sr CurrentUser ^
   -a sha256 -cy authority -sky signature ^
   -sv Demo_CA.pvk Demo_CA.cer

makecert -pe -n "CN=Demo_SPC" -a sha256 -cy end ^
   -sky signature ^
   -ic Demo_CA.cer -iv Demo_CA.pvk ^
   -sv Demo_SPC.pvk Demo_SPC.cer

pvk2pfx -pvk Demo_SPC.pvk -spc Demo_SPC.cer ^
   -pfx Demo_SPC.pfx ^
   -po x

inf2cat /drv:driver /os:XP_X86,Vista_X64,Vista_X86,7_X64,7_X86 /v

signtool sign /d "description" /du "www.yoyodyne.com" ^
   /f Demo_SPC.pfx ^
   /p x ^
   /v driver\demoprinter.cat

certutil -addstore Root Demo_CA.cer

rem Needs administrator. If this command works, the driver is properly signed.
devcon install driver\demoprinter.inf LPTENUM\Yoyodyne_IndustriesDemoPrinter_F84F

rem Now uninstall the test driver and certificate.
devcon remove driver\demoprinter.inf LPTENUM\Yoyodyne_IndustriesDemoPrinter_F84F

certutil -delstore Root Demo_CA

As stated in the answer, in order to use a non deprecated way to sign your own script, one should use New-SelfSignedCertificate.

  1. Generate the key:
New-SelfSignedCertificate -DnsName [email protected] -Type CodeSigning -CertStoreLocation cert:\CurrentUser\My
  1. Export the certificate without the private key:
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).

  1. Import it as Trusted Publisher
Import-Certificate -FilePath .\code_signing.crt -Cert Cert:\CurrentUser\TrustedPublisher
  1. Import it as a Root certificate authority.
Import-Certificate -FilePath .\code_signing.crt -Cert Cert:\CurrentUser\Root
  1. Sign the script (assuming here it's named script.ps1, fix the path accordingly).
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.

1) Create certificate:
$cert = New-SelfSignedCertificate -DnsName www.yourwebsite.com -Type CodeSigning -CertStoreLocation Cert:\CurrentUser\My

2) set the password for it:
$CertPassword = ConvertTo-SecureString -String "my_passowrd" -Force –AsPlainText

3) Export 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"