Self-signed certificates are an easy way to perform tests and other less important tasks. Self-signed certificates do not have a trusted certificate chain backing them up and are signed by the user who created them. If you trust the entity that signed the certificate, you can use it as you would a properly validated certificate.

If you need to create a self-signed certificate, you can do it with PowerShell. In this article, you’ll learn how to create a self-signed certificate in PowerShell.

Creating a self-signed certificate

To create a self-signed certificate with PowerShell, you can use the New-SelfSignedCertificate cmdlet. This cmdlet is included in the PKI module.

There are many options for creating certificates. Common types of self-signed certificates are SSLServerAuthentication (default for cmdlet) and CodeSigning. You can also create a DocumentEncryptionCert, which is very useful for encrypting files, and finally a Custom certificate that allows you to specify many custom options.

Let’s go ahead and create a regular SSLServerAuthentication certificate. This is the one that is generally used to protect websites with SSL encryption. You can see an example below. In this example, the certificate is stored in the Cert:LocalMachineMy Certificate Store.

$Params = @{
    "DnsName"           = @("mywebsite.com","www.mywebsite.com")
    "CertStoreLocation" = "Cert:LocalMachineMy"
    "NotAfter"          = (Get-Date).AddMonths(6)
    "KeyAlgorithm"      = "RSA"
  "KeyLength"         = "2048"
}

PS C:> New-SelfSignedCertificate @Params

PSParentPath: Microsoft.PowerShell.SecurityCertificate::LocalMachineMy

Thumbprint                                Subject              EnhancedKeyUsageList
----------                                -------              --------------------
4EFF6B1A0F61B4BG692C77F09889BD151EE8BB58  CN=mywebsite.com     {Client Authentication, Server Authentication}

If all went well, you should now have a newly created certificate! You will notice that the output returns the subject but the subject only displays the first item passed to it through the DnsName setting. This is because the second URL is on the alternate topic list.

* Note that if you try to run it, not as administrator, you will get an error message like below:

New-SelfSignedCertificate: CertEnroll::CX509Enrollment::_CreateRequest: Access denied. 0x80090010 (-2146893808 NTE_PERM)

As you can see with the Access denied, you are not yet authorized to run it. *

Find information about our certificate

Make sure the certificate was created as expected. To find information about a particular certificate with PowerShell, you can use the Get-ChildItem cmdlet, just like you might list files in a directory.

PS C:> Get-ChildItem -Path "Cert:LocalMachineMy" | Where-Object Thumbprint -EQ 4EFF6B1A0F61B4BF692C77F09889AD151EE8BB58 | Select-Object *

PSPath                   : Microsoft.PowerShell.SecurityCertificate::LocalMachineMy4EFF6B1A0F61B4BF692C77F09889AD151EE8BB58
                           58
PSParentPath             : Microsoft.PowerShell.SecurityCertificate::LocalMachineMy
PSChildName              : 4EFF6B1A0F61B4BF692C77F09889AD151EE8BB58
PSDrive                  : Cert
PSProvider               : Microsoft.PowerShell.SecurityCertificate
PSIsContainer            : False
EnhancedKeyUsageList     : {Client Authentication (1.3.6.1.5.5.7.3.2), Server Authentication (1.3.6.1.5.5.7.3.1)}
DnsNameList              : {mywebsite.com, www.mywebsite.com}
SendAsTrustedIssuer      : False
EnrollmentPolicyEndPoint : Microsoft.CertificateServices.Commands.EnrollmentEndPointProperty
EnrollmentServerEndPoint : Microsoft.CertificateServices.Commands.EnrollmentEndPointProperty
PolicyId                 :
Archived                 : False
Extensions               : {System.Security.Cryptography.Oid, System.Security.Cryptography.Oid,
                           System.Security.Cryptography.Oid, System.Security.Cryptography.Oid}
FriendlyName             :
HasPrivateKey            : True
PrivateKey               : System.Security.Cryptography.RSACng
IssuerName               : System.Security.Cryptography.X509Certificates.X500DistinguishedName
NotAfter                 : 6/22/2020 11:50:15 AM
NotBefore                : 12/22/2019 10:40:20 AM
PublicKey                : System.Security.Cryptography.X509Certificates.PublicKey
RawData                  : {48, 130, 3, 55…}
SerialNumber             : 608C4D5E6B8D41B44ADDC6BD725FE264
SignatureAlgorithm       : System.Security.Cryptography.Oid
SubjectName              : System.Security.Cryptography.X509Certificates.X500DistinguishedName
Thumbprint               : 4EFF6B1A0F61B4BF692C77F09889AD151EE8BB58
Version                  : 3
Handle                   : 2628421609632
Issuer                   : CN=mywebsite.com
Subject                  : CN=mywebsite.com

There is a lot of interesting information here, but you might notice in the DnsNameList that both sites are now displayed. In addition, the NotAfter the date is correctly entered to be 6 months from the creation date.

Code signing certificate

If you are working in PowerShell, you will know execution policies. If you have an execution policy set to AllSigned then you will need to sign every script that runs on your system. To create a certificate to do this, it’s pretty simple!

PS C:> New-SelfSignedCertificate -Type 'CodeSigningCert' -DnsName 'MyHost'

PSParentPath: Microsoft.PowerShell.SecurityCertificate::LocalMachineMY

Thumbprint                                Subject              EnhancedKeyUsageList
----------                                -------              --------------------
14D535EG834370293BA103159EB00876A79959D8  CN=MyHost            Code Signing

Document protection certificate

You may not have encountered this before, but PowerShell, along with the Data Protection API, can encrypt files on your system using a Document Protection Certificate. Using the New-SelfSignedCertificate cmdlet, we can easily create a certificate to encrypt your documents.

$Params = @{
    "DnsName"           = "MyHost"
    "CertStoreLocation" = "Cert:CurrentUserMy"
    "KeyUsage"          = "KeyEncipherment","DataEncipherment","KeyAgreement"
    "Type"              = "DocumentEncryptionCert"
}

PS C:> New-SelfSignedCertificate @Params

Thumbprint                                Subject              EnhancedKeyUsageList
----------                                -------              --------------------
14D535EG934370293BA203159EB00876A79959D8  CN=MyHost            Document Encryption

With this type of certificate, you can now use the created certificate to encrypt and decrypt content using PowerShell commands such as Protect-CMSMessage and UnProtect-CMSMessage.

Encrypting / decrypting content like this becomes useful if you need to transmit the encrypted data, as you can then use this certificate on another system to decrypt the data. If you rely on the Data Protection Standard API (DPAPI) built into Windows, you will not be able to decrypt data on other systems or for other users.

summary

PowerShell makes creating self-signed certificates incredibly easy to do. These certificates have a multitude of uses, but an important note to remember is that they should only be used for testing. You will not have a valid certificate chain of trust to validate your self-signed certificates.

Seeing how fast and easy it is to create self-signed certificates, you can start doing it today and properly encrypting any connections or data you need!

LEAVE A REPLY

Please enter your comment!
Please enter your name here