How to create and install X.509 self signed certificates in Windows 10 without user interaction? How to create and install X.509 self signed certificates in Windows 10 without user interaction? powershell powershell

How to create and install X.509 self signed certificates in Windows 10 without user interaction?


I just tested your code with the signtool.exe coming from my Visual Studio 2017 installation and things seems to work.

So I would really like to see the code / command you use for signing the files. Even more I would like to see the real output from the error that you are seeing. Could you try your signing process manually / by hand at first, so we are sure that we are focusing on the correct issue?

With that said, I spent some time digging around to answer some of the other questions you had.

Solving the first part of you wanting to only see

All issuance policiesAll application policies

This is solved with the TextExtension parameter:

-TextExtension @("2.5.29.37={text}1.3.6.1.4.1.311.10.12.1")

Solving the part that you wanted the

Subject Type = CA

This is solved with the TextExtension parameter:

-TextExtension @("2.5.29.19={text}CA=1&pathlength=3")

The path length is used to limit how many levels of children that can use the certificate. Please read more here. The value 3 is just something is used while testing.

We then need to combine those 2 different TextExtensions entries:

-TextExtension @("2.5.29.37={text}1.3.6.1.4.1.311.10.12.1", "2.5.29.19={text}CA=1&pathlength=3")

Which will have us write the updated script like this

$rootCert = New-SelfSignedCertificate -KeyExportPolicy Exportable -CertStoreLocation cert:\CurrentUser\My -DnsName "Development Root CA" -NotAfter (Get-Date).AddYears(5) -TextExtension @("2.5.29.37={text}1.3.6.1.4.1.311.10.12.1", "2.5.29.19={text}CA=1&pathlength=3") -KeyusageProperty All -KeyUsage CertSign,CRLSign,DigitalSignature# Export the root authority private key.[System.Security.SecureString] $password = ConvertTo-SecureString -String "passwordx" -Force -AsPlainText[String] $rootCertPath = Join-Path -Path cert:\CurrentUser\My\ -ChildPath "$($rootcert.Thumbprint)"Export-PfxCertificate -Cert $rootCertPath -FilePath "MyCA.pfx" -Password $passwordExport-Certificate -Cert $rootCertPath -FilePath "MyCA.crt"# Create a "MySPC" certificate signed by our root authority.$cert = New-SelfSignedCertificate -CertStoreLocation Cert:\LocalMachine\My -DnsName "MySPC" -Signer $rootCert -Type CodeSigningCert# Save the signed certificate with private key into a PFX file and just the public key into a CRT file.[String] $certPath = Join-Path -Path cert:\LocalMachine\My\ -ChildPath "$($cert.Thumbprint)"Export-PfxCertificate -Cert $certPath -FilePath MySPC.pfx -Password $passwordExport-Certificate -Cert $certPath -FilePath "MySPC.crt"# Add MyCA certificate to the Trusted Root Certification Authorities.$pfx = new-object System.Security.Cryptography.X509Certificates.X509Certificate2$pfx.import("MyCA.pfx", $password, "Exportable,PersistKeySet")$store = new-object System.Security.Cryptography.X509Certificates.X509Store(    [System.Security.Cryptography.X509Certificates.StoreName]::Root,    "localmachine")$store.open("MaxAllowed")$store.add($pfx)$store.close()# Import certificate.Import-PfxCertificate -FilePath MySPC.pfx cert:\CurrentUser\My -Password $password

But like I stated earlier, your code seems to generate the correct certificates because I was able to use the certificate it generated and sign an .net EXE file with it.

Before signing

Before signing

Signing

SignTool sign /n "MySPC" 2LCS.exe

After signing

After signing

Update based on the new information

You need to specify the /pa switch on your verify command.

https://knowledge.digicert.com/solution/SO21771.html

https://docs.microsoft.com/en-us/windows/desktop/seccrypto/signtool

Question is if you would see the same with the makecert certificates?

Updated with working code

Your focus on the properties of the certificate got me down the wrong road. Based on a discussion from here I learned that we might need to have it created as a Class 3 code signing. I removed the 1.3.6.1.4.1.311.10.12.1 EKU extension and replaced it with 1.3.6.1.5.5.7.3.3. Please see below code example.

$rootCert = New-SelfSignedCertificate -KeyExportPolicy Exportable -CertStoreLocation cert:\CurrentUser\My -DnsName "Development Root CA" -NotAfter (Get-Date).AddYears(5) -TextExtension @("2.5.29.19={text}CA=1&pathlength=3", "2.5.29.37={text}1.3.6.1.5.5.7.3.3") -KeyusageProperty All -KeyUsage CertSign,CRLSign,DigitalSignature #-Type CodeSigningCert# Export the root authority private key.[System.Security.SecureString] $password = ConvertTo-SecureString -String "passwordx" -Force -AsPlainText[String] $rootCertPath = Join-Path -Path cert:\CurrentUser\My\ -ChildPath "$($rootcert.Thumbprint)"Export-PfxCertificate -Cert $rootCertPath -FilePath "MyCA.pfx" -Password $passwordExport-Certificate -Cert $rootCertPath -FilePath "MyCA.crt"# Create a "MySPC" certificate signed by our root authority.$cert = New-SelfSignedCertificate -CertStoreLocation Cert:\LocalMachine\My -DnsName "MySPC" -Signer $rootCert -Type CodeSigningCert# Save the signed certificate with private key into a PFX file and just the public key into a CRT file.[String] $certPath = Join-Path -Path cert:\LocalMachine\My\ -ChildPath "$($cert.Thumbprint)"Export-PfxCertificate -Cert $certPath -FilePath MySPC.pfx -Password $passwordExport-Certificate -Cert $certPath -FilePath "MySPC.crt"# Add MyCA certificate to the Trusted Root Certification Authorities.$pfx = new-object System.Security.Cryptography.X509Certificates.X509Certificate2$pfx.import("MyCA.pfx", $password, "Exportable,PersistKeySet")$store = new-object System.Security.Cryptography.X509Certificates.X509Store(    [System.Security.Cryptography.X509Certificates.StoreName]::Root,    "localmachine")$store.open("MaxAllowed")$store.add($pfx)$store.close()# Import certificate.Import-PfxCertificate -FilePath MySPC.pfx cert:\CurrentUser\My -Password $password

I ran the following signing command:

enter image description here

And after that I ran the verification command:

enter image description here

With that in place I believe that you should have a working solution. Please test it, verify and then extend it to include your timestamp signing as well.


Installation of certificate on cert store do by Certificate Propagation service.

So you can scan(Scan API) Certificate Propagation service and develop like it.

You can use API Monitor.