Skip to content

Instantly share code, notes, and snippets.

Last active January 28, 2022 20:03
Show Gist options
  • Save deadlydog/9f87fba75d611b4f1757af7767aa2d05 to your computer and use it in GitHub Desktop.
Save deadlydog/9f87fba75d611b4f1757af7767aa2d05 to your computer and use it in GitHub Desktop.
PowerShell script that imports a .pfx certificate file. Useful to do before building the solution on a build server. For more info, see
param([string] $PfxFilePath, $Password)
# You may provide a [string] or a [SecureString] for the $Password parameter.
$absolutePfxFilePath = Resolve-Path -Path $PfxFilePath
Write-Output "Importing store certificate '$absolutePfxFilePath'..."
Add-Type -AssemblyName System.Security
$cert = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2
$cert.Import($absolutePfxFilePath, $Password, [System.Security.Cryptography.X509Certificates.X509KeyStorageFlags]"PersistKeySet")
$store = new-object -argumentlist "MY", CurrentUser
Copy link

@deadlydog, What the value should be set for "MY"?

Copy link

@deadlydog, What the value should be set for "MY"?

MY is the correct value. See the docs for more info.

Copy link

What the hell is this?

System.Security.Cryptography.CryptographicException: Keyset does not exist

Copy link

Umm, import-pfxcertificate is a native PS capability?

Copy link

@armplinker Import-PfxCertificate is the name of the PowerShell script file here; not a native PowerShell cmdlet. So you would want to copy the code from this gist into a file called Import-PfxCertificate.ps1 and then call it with the appropriate parameter values.

Copy link

armplinker commented Jan 28, 2022

Yes, thank you @deadlydog for your clarification. Configuring this particular cmdlet is something of a black art, as I have come to appreciate in the last horrible 24 hours, after I realized my ole MakeCert.exe etc. approach was obsolete. In particular there is one cmdlet parameter
-KeyUsage None that seems to misbehave, in ways I am not sure affect me.

The cert location should be cert:LocalMachine/my as indicated by @deadlydog. The following not only assumes that, but has the arrogance to stick the cert into Cert:\LocalMachine\AuthRoot

Here is where my current attempt to create a signing certificate from scratch for signing SQL Server CLR assemblies is:
# if you want a PFX file as a result
$pfxFileName="<your PFX_FILE_NAME_GOES_HERE.pfx";
$certFileName="<your CERT_FILE_NAME GOES HERE.cer";
# * is a dummy, like me...
$cert=New-SelfSignedCertificate -Type CodeSigningCert -DnsName *,$env:COMPUTERNAME -FriendlyName RIDOT_BrM_TestCert -Subject $env:COMPUTERNAME
-Provider "Microsoft Strong Cryptographic Provider" -HashAlgorithm "SHA256" #and you may want to use a different HashAlgorithm
-KeyLength 2048 -KeyExportPolicy Exportable -CertStoreLocation Cert:\LocalMachine\My -NotAfter (Get-Date).AddYears(10) -KeyUsageProperty All
-KeyUsage None `
-TextExtension @("{text},,")
# the TextExtension thing is the black art. These magic strings make the certificate cable of Server Authentication, Client Authentication, and Code Signing
$CertPassword = ConvertTo-SecureString -String "<YOUR ULTRA SECURE PASSWORD GOES HERE IN TEXT" -Force -AsPlainText

make a .cer file

$certFile = Export-Certificate -Cert $cert -FilePath $certFileName -Type CERT -Verbose -Force
Import-Certificate -CertStoreLocation $certStoreLocation -FilePath $certFile.FullName

Remove-Item $certFile.FullName

_# I kept my cer file around because SQL Server wants one to import to create a login to associate with a signed DLL...

HOWEVER, the cer does not provide a PVK directly, so, you may wish to export the certificate from the server using the windows certificate manager

because you can elect to export a private key file - This is discussed abundantly elsewhere..._

$ips = [System.Net.Dns]::GetHostAddresses("").IPAddressToString -like "."
_# again, you need to let your host know that this domain you are using is ok in the server's hosts file. I actually don't need this AFAIC_T
Add-Content C:\Windows\System32\drivers\etc\hosts "$ips *"

make a pfx file

$cert | Export-PfxCertificate -FilePath $pfxFileName -Password $CertPassword -Verbose -Force

# and at the end of this, you still have an untrusted certificate

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment