Powershell code signing

From wikinotes

Documentation

New-SelfSignedCertificate docs https://docs.microsoft.com/en-us/powershell/module/pkiclient/new-selfsignedcertificate?view=win10-ps
Import-Certificate https://docs.microsoft.com/en-us/powershell/module/pkiclient/Import-Certificate?view=win10-ps
Export-Certificate (public?) https://docs.microsoft.com/en-us/powershell/module/pkiclient/Export-Certificate?view=win10-ps
Export-PfxCertificate (prvkey&cert) https://docs.microsoft.com/en-us/powershell/module/pkiclient/export-pfxcertificate?view=win10-ps
Set-AuthenticodeSignature https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.security/set-authenticodesignature?view=powershell-6
SignTool.exe https://docs.microsoft.com/en-us/windows/win32/seccrypto/signtool

Tutorials

SO- self-signed codecert windows https://stackoverflow.com/questions/84847/how-do-i-create-a-self-signed-certificate-for-code-signing-on-windows
SO- self-signed/trusted cert windows https://stackoverflow.com/questions/48509114/how-to-create-a-working-trusted-and-or-self-signed-certificate-for-a-windows-10

Tools

certmgr.msc CurrentUser certificates
certlm.msc LocalMachine certificates

List Certificates

Get-ChildItem cert:\CurrentUser\My   # HKCU certs
Get-ChildItem cert:\LocalMachine\My  # HKLM certs

See Documentation for New-SelfSignedCertificate -CertStoreLocation for all locations.

Create Self-Signed Certs

# CodeSigningCert  (works, but still unknown publisher - even with friendlyname set)
New-SelfSignedCertificate `
  -DnsName domain.com `
  -Type CodeSigningCert `
  -CertStoreLocation cert:\CurrentUser\My `
# official package-signing docs (did not work for me)
# https://docs.microsoft.com/en-us/windows/msix/package/create-certificate-package-signing
New-SelfSignedCertificate `
  -Type Custom `
  -Subject "CN=Contoso Software, O=Contoso Corporation, C=US" `
  -KeyUsage DigitalSignature `
  -FriendlyName "Your friendly name goes here" `
  -CertStoreLocation "Cert:\CurrentUser\My" `
  -TextExtension @("2.5.29.37={text}1.3.6.1.5.5.7.3.3", "2.5.29.19={text}")

Export Certificate

$all_certs = Get-ChildItem cert:\CurrentUser\My -CodeSigningCert

Export-Certificate `
  -Cert $all_certs[0] `
  -FilePath code_signing.crt

Export PrivateKey+Certificate

$all_certs = Get-ChildItem cert:\CurrentUser\My -CodeSigningCert
$mypwd = ConvertTo-SecureString -String "1234" -Force -AsPlainText

# NOTE: you must either password-protect pfx, 
#       or restrict it to a domain/user (See -ProtectTo)
Export-PfxCertificate `
  -cert $all_certs[0] `
  -Password $mypwd `
  -FilePath my_prv_cert.pfx

Import Certificate

# import certificate as TRUSTED-PUBLISHER
Import-Certificate `
  -FilePath .\code_signing.crt `
  -Cert Cert:\CurrentUser\TrustedPublisher

# import certificate as ROOT-CERTIFICATE-AUTHORITY
Import-Certificate `
  -FilePath .\code_signing.crt `
  -Cert cert:\CurrentUser\Root

Signing Code

$all_certs = Get-ChildItem cert:\CurrentUser\My -CodeSigningCert

Set-AuthenticodeSignature `
  ./your_script.ps1 `           # alternatively, yourfile.exe
  -Certificate $all_certs[0]

Deleting Certificate

$all_certs = Get-ChildItem cert:\CurrentUser\My -CodeSigningCert
$all_certs[0] | Remove-Item