I am attempting to create a self signed certificate with PowerShell and protect the private key with a TPM 2.0 module.
I can create a cert backed by the TPM with :
New-SelfSignedCertificate -Provider "Microsoft Platform Crypto Provider" -Subject "CN=Test Cert" -CertStoreLocation "Cert:\LocalMachine\My"
I can cert with P384 with:
New-SelfSignedCertificate -Subject "CN=Test Cert" -KeyAlgorithm ECDSA_P384 -HashAlgorithm SHA384 -CurveExport CurveName -CertStoreLocation "Cert:\LocalMachine\My"
But combining the two fails with "Provider not defined":
New-SelfSignedCertificate -Provider "Microsoft Platform Crypto Provider" -Subject "CN=Test Cert" -KeyAlgorithm ECDSA_P384 -HashAlgorithm SHA384 -CurveExport CurveName -CertStoreLocation "Cert:\LocalMachine\My"
At this point I am unsure if this is a limitation of the MS provider, a limitation of the TPM module I have, or a result of the current configuration Windows 10 and therefore perhaps something I can address.
Can anyone offer any insight as to the root cause and perhaps a resolution?
Thanks
with the following code I generated a new Self Signed Code Signing Certificate for Powershell Scripts in my CA (Not Enterprise PKI!) and deployed it via a GPO (within the PS Skript and the Root Code Signing Certificate):
# Create a certificate to use for signing powershell scripts
$selfsigncert = New-SelfSignedCertificate `
-Subject "CN=PowerShell Code Signing" `
-KeyAlgorithm RSA `
-KeyLength 2048 `
-Type CodeSigningCert `
-CertStoreLocation Cert:\LocalMachine\My\
# Move the root cert into Trusted Root CAs
Move-Item "Cert:\LocalMachine\My\$($selfsigncert.Thumbprint)" Cert:\LocalMachine\Root
# Obtain a reference to the code signing cert in Trusted Root
$selfsignrootcert = "Cert:\LocalMachine\Root\$($selfsigncert.Thumbprint)"
Get-ChildItem cert:\LocalMachine\Root -CodeSigningCert
#Sign the PowerShell Script
Set-AuthenticodeSignature xxx.ps1 #(Get-ChildItem cert:\LocalMachine\Root -codesigning)[0] -IncludeChain "All"
# Verify if signature is valid
Get-AuthenticodeSignature .\xx.ps1 -Verbose | fl
# Edit Displayname of Certificate to uniquely identify the cert
(Get-ChildItem -Path Cert:\LocalMachine\Root\(ThumbprintNumer)).FriendlyName = "XXXX"
Now this works properly, my powershell scripts are getting signed and I can deploy it on my domain with GPO. The only bad thing is the expiration date. When I create the cert like the way I explained here, it is invalid after 1 year. Is it possible, that I can edit the expiration date when I create the cert or renew it manually?
I hope somebody has an answer for me :)
Greetings
TheLizadator
Using makecert.exe I can take a pvk file and generate a CRL using the following command:
makecert.exe -crl -n "CN=Foobar" -r -sv "Foobar.pvk" "Foobar.crl"
What is the equivalent Powershell command?
The following code uses Powershell to generate the PVK and CER files, but I can't figure out how to generate the CRL
$rootcert = New-SelfSignedCertificate -DnsName "CN=Foobar" -CertStoreLocation cert:\LocalMachine\My
$PFXPass = ConvertTo-SecureString -String "my password" -Force -AsPlainText
Export-PfxCertificate -Cert $('cert:\LocalMachine\My\' + $rootcert.Thumbprint) -Password $PFXPass -FilePath "Foobar.pvk"
Export-Certificate -Cert $('cert:\LocalMachine\My\' + $rootcert.Thumbprint) -FilePath "Foobar.cer"
Three things to consider:
makecert.exe tool is deprecated and no longer recommended for use: MakeCert.
CRL generation for self-signed certificates is useless and makes no sense. Revocation for self-signed certificates is undefined, because it leads to an egg and chicken problem. And they use explicit trust.
Manual CRL generation is an unmaintainable solution. You should use CA software to run your own CA and automate CA-specific routines.
I'm trying to sign a .ps1 using self-signed certificates (the use case is for scripts I write myself on my private dev station, so no need to use - or pay for -
a real CA). However, no matter how many guides on the topic of certificates generation and digital signatures I read, I can't seem to get it working.
Here's what I have accomplished so far:
# Create a certificate to use as trusted root of the signing chain
$root = New-SelfSignedCertificate `
-Subject "CN=PowerShell Trusted Authority" `
-FriendlyName "PowerShell Trusted Authority" `
-KeyUsageProperty Sign `
-KeyUsage CertSign, CRLSign, DigitalSignature `
-CertStoreLocation Cert:\LocalMachine\My\ `
-NotAfter (Get-Date).AddYears(10)
# Create a certificate to use for signing powershell scripts
New-SelfSignedCertificate `
-Signer $root `
-Subject "CN=PowerShell Code Signing" `
-KeyAlgorithm RSA `
-KeyLength 2048 `
-Type CodeSigningCert `
-CertStoreLocation Cert:\LocalMachine\My\
# Move the root cert into Trusted Root CAs
Move-Item "Cert:\LocalMachine\My\$($root.Thumbprint)" Cert:\LocalMachine\Root
All of the above done from an administrative powershell instance. After that is done, I can see both certificates, in the expected locations, in the management console, and the certificate path of the signing cert checks out as valid.
I then open a regular PS prompt and attempt to sign the script:
# Obtain a reference to the signing certificate
PS> $cert = Get-ChildItem Cert:\LocalMachine\My\ -CodeSigningCert
# Attempt at signing
PS> Set-AuthenticodeSignature .\Microsoft.PowerShell_profile.ps1 $cert
Directory: C:\Users\tomas\Documents\WindowsPowerShell
SignerCertificate Status Path
----------------- ------ ----
UnknownError Microsoft.PowerShell_profile.ps1
As you can see, the actual signing fails. Looking at the powershell file, I see that no signature has been appended to the script.
If I do the signing from an admin prompt, I seem to get a little further; a signature block is added to the script, and the thumbprint of the signing cert is printed in the output from Set-AuthenticodeSignature, but the status is still UnknownError and execution under the AllSigned policy is still not allowed.
# Output some info about the certificate:
PS> $cert | Format-List
Subject : CN=PowerShell Code Signing
Issuer : CN=PowerShell Trusted Authority
Thumbprint : <omitted>
FriendlyName :
NotBefore : 9/20/2017 10:48:59 PM
NotAfter : 9/20/2018 11:08:59 PM
Extensions : {System.Security.Cryptography.Oid, System.Security.Cryptography.Oid,
System.Security.Cryptography.Oid, System.Security.Cryptography.Oid}
I've tried a multitude of variants of New-SelfSignedCertificate incantations, especially to generate the certificate for code signing, but always with the same status message (UnknownError).
My ultimate goal here is to be able to have Set-ExecutionPolicy AllSigned and still run scripts that I've created myself. What am I missing in this process to make that work?
Thinking about this, you don't need a certificate chain trust, therefore, you don't need your first certificate. You can use the second certificate and move it into your Trusted Root folder and it will work. Using the first certificate and then creating another certificate seems to fail because the 'root' is self signed and then can't sign another certificate.
SELF SIGNED CERTIFICATE method
# Create a certificate to use for signing powershell scripts
$selfsigncert = New-SelfSignedCertificate `
-Subject "CN=PowerShell Code Signing" `
-KeyAlgorithm RSA `
-KeyLength 2048 `
-Type CodeSigningCert `
-CertStoreLocation Cert:\LocalMachine\My\
# Move the root cert into Trusted Root CAs
Move-Item "Cert:\LocalMachine\My\$($selfsigncert.Thumbprint)" Cert:\LocalMachine\Root
# Obtain a reference to the code signing cert in Trusted Root
$selfsignrootcert = "Cert:\LocalMachine\Root\$($selfsigncert.Thumbprint)"
# Sign script
Set-AuthenticodeSignature C:\powershell.ps1 $selfsignrootcert
If you have access to an Enterprise Root CA, you can use the method you have used in your question.
ENTERPRISE ROOT CA method (same method as you have in your question) - you need to know your Root CA certificate thumbprint
# Get Enterprise Root CA thumbprint
$rootcert = get-childitem Cert:\LocalMachine\Root\XXXXXXXXXXXX
# Generate certificate
$fromrootcert = New-SelfSignedCertificate `
-Signer $rootcert `
-Subject "CN=PowerShell Code Signing" `
-KeyAlgorithm RSA `
-KeyLength 2048 `
-Type CodeSigningCert `
-CertStoreLocation Cert:\LocalMachine\My\
# Sign script
Set-AuthenticodeSignature C:\powershell.ps1 $fromrootcert
$cert = New-SelfSignedCertificate -CertStoreLocation Cert:\CurrentUser\My -Type CodeSigningCert -Subject "Code Signing"
Move-Item -Path $cert.PSPath -Destination "Cert:\CurrentUser\Root"
Set-AuthenticodeSignature -FilePath c:\go.ps1 -Certificate $cert
source
https://blogs.u2u.be/u2u/post/creating-a-self-signed-code-signing-certificate-from-powershell
I Want to Create a Point-To-Site vpn from a Virtual netwerk in azure.
For the authentication I want to use certificates, the root certificate is generated in azure key vault. I don't want to authenticate with the rootCertificate.pfx but with the clientCertificate.pfx.
The requirements are
that I don't use an external certificate provider.
I use as much powershell as possible
We followed this Documentation to Create a self-signed certificate in key vault.
https://blogs.technet.microsoft.com/kv/2016/09/26/get-started-with-azure-key-vault-certificates/
After I Created a Root Certificate, it is placed within the key vault. (public part in secrets, private part in keys)
Next We copy/paste the public part(Base64) in the Virtual Network Gateway -> point-to-site Configuration -> Root Certificates
Then I used this powershell script to generate a clientCertificate from the rootCertificate that we made earlier. We export it to our Local Hard Drive.
Login-AzureRmAccount
$kvSecret = Get-AzureKeyVaultSecret -VaultName "akv-contoso-test" -Name "ContosoFirstCertificate"
$kvSecretBytes = [System.Convert]::FromBase64String($kvSecret.SecretValueText)
$rootCertificate = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2 -ArgumentList #($kvSecretBytes, $null, [System.Security.Cryptography.X509Certificates.X509KeyStorageFlags]::Exportable)
$certStore = New-Object System.Security.Cryptography.X509Certificates.X509Store
$certStore.Open([System.Security.Cryptography.X509Certificates.OpenFlags]::ReadWrite)
$certStore.Add($rootCertificate)
$clientCertificate = New-SelfSignedCertificate -Type Custom -KeySpec Signature -Subject "CN=Point To Site VPN Client" -KeyExportPolicy Exportable -HashAlgorithm sha256 -KeyLength 2048 -Signer $rootCertificate -TextExtension #("2.5.29.37={text}1.3.6.1.5.5.7.3.2")
$securePassword = ConvertTo-SecureString -String "mysecret" -AsPlainText -Force
Export-PfxCertificate -Cert $clientCertificate -Password $securePassword -FilePath "C:\Users\User\Desktop\Certificates\Point To Site VPN Client.pfx" -ChainOption BuildChain
$certStore.Close()
After that we install the "Point To Site VPN Client.pfx"
The public root certificate is installed in the Trusted Root Certification Authorities. In the chain of trust of my client certificate, the Root Certificate says the following "This certificate is not valid for the selected purpose".
Now I want to connect to the vpn with the Client Certificate.
He tells that the message received was unexpected or badly formatted.
My guess is that there is a problem when we want to generate the Client Certificate out of the keyvault (script above).
Chain of trust and Connection Error