Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
This post will demonstrate using PowerShell cmdlets to create, read, and delete certificates. Spoiler alert: it’s dead simple.
Background
I was working through the example Authenticating to Azure AD in daemon apps with certificates and I saw this:
makecert -r -pe -n "CN=TodoListDaemonWithCert" -ss My -len 2048 TodoListDaemonWithCert.cer -sv TodoListDaemonPrivateKey.pvk
Easy to read, right? I mean, anyone can read that and understand it will create a self-signed certificate where the private key is exportable and store it in the current user’s personal certificate store, right?
Inevitably, when I tell someone to “just use a self-signed certificate”, I inevitably get a question asking something like “Makecert.exe is not on my computer, where do I get it from?” You need to download the Windows SDK in order to obtain it, but that’s a pretty large tax for what seems like a simple function, creating a self-signed certificate. The sample then goes on with some more code to read a .CER file using PowerShell, using the .NET X509Certificate2 class:
$cer = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2
$cer.Import("TodoListDaemonWithCert.cer")
$bin = $cer.GetRawCertData()
$base64Value = [System.Convert]::ToBase64String($bin)
$bin = $cer.GetCertHash()
$base64Thumbprint = [System.Convert]::ToBase64String($bin)
$keyid = [System.Guid]::NewGuid().ToString()
It struck me that this is fairly complicated for something that should have just been 1 line of code.
Working With Certificates in PowerShell
If you Google with Bing you’ll see a whole bunch of blog posts that show fairly long-winded examples of creating self-signed certificates using the .NET X509Certificate2 class. Turns out it’s so much simpler than that. The equivalent of the above command is:
New-SelfSignedCertificate
- $cert = New-SelfSignedCertificate -Subject "CN=TodoListDaemonWithCert" -CertStoreLocation cert:\CurrentUser\My -Provider "Microsoft Strong Cryptographic Provider"
That’s it. No need to install the Windows SDK.
The cmdlet returns the certificate object (which is actually a System.Security.Cryptography.X509Certificates.X509Certificate2 .NET type). So you can just use a variable to store it:
New-SelfSignedCertificate
- $cert = New-SelfSignedCertificate -Subject "CN=TodoListDaemonWithCert" -CertStoreLocation cert:\CurrentUser\My -Provider "Microsoft Strong Cryptographic Provider"
Since you have an X509Certificate2 object, you can easily interrogate its properties:
Certificate Properties
- Write-Host "base64Cert: " ([System.Convert]::ToBase64String($cert.GetRawCertData()))
- Write-Host "base64CertHash:" ([System.Convert]::ToBase64String($cert.GetCertHash()))
- Write-Host "keyID:" ([System.Guid]::NewGuid().ToString())
Need to get an existing certificate by a property such as its Subject? You can use the Get-ChildItem cmdlet and specify the path to the certificate store.
Get-ChildItem
- $cert = Get-ChildItem -Path cert:\CurrentUser\My | ?{$_.Subject -eq "CN=TodoListDaemonWithCert"}
Need to exporting the public key? Straightforward.
Export Public Key
- Export-Certificate -Type CERT -Cert $cert -FilePath "c:\temp\sample.cer"
What about the private key?
Export Private Key
- $cred = Get-Credential
- Export-PfxCertificate -Cert $cert -Password $cred.Password -FilePath "c:\temp\sample.pfx"
How about removing a certificate? Also very simple.
Removing Certificates
- Remove-Item -Path ("cert:\CurrentUser\My\" + $cert.Thumbprint)
Summary
I’m guilty, I have been doing this a long time and stuck in my ways. I default to makecert.exe because that’s what I know, but it’s useful to have tools that are far easier to read and understand.