Self-signed certificates can be used to secure web connections, encrypt data sent over the internet, and can be used to authenticate the identity of the server to the client. In this blog post, we will cover the basics of self-signed certificates, how to create them, and how to use them to secure your web connections.
Creating a Self-Signed Certificate
There are several ways to create a self-signed certificate, but in this blog post, we will cover two popular methods: using mkcert and using PowerShell in-built (New-SelfSignedCertificate) cmdlet.
Method 1: Using mkcert
mkcert is a simple command-line tool that can be used to create a self-signed certificate. To create a self-signed certificate using mkcert, you can use script at and can run on PowerShell.
# Execute it on Powershell ./Generate-SelfSignedCertificate-mkcert.ps1 | |
$hostName = "kb.sunilcloudops.com" | |
$ErrorActionPreference = "Stop"; | |
################################## | |
# Configure TLS/HTTPS certificates | |
################################## | |
Write-Host "Generating Certificates ..." -ForegroundColor Green | |
try { | |
$mkcert = ".\mkcert.exe" | |
if ($null -ne (Get-Command mkcert.exe -ErrorAction SilentlyContinue)) { | |
# mkcert installed in PATH | |
$mkcert = "mkcert" | |
} elseif (-not (Test-Path $mkcert)) { | |
Write-Host "Downloading and installing mkcert certificate tool..." -ForegroundColor Green | |
Invoke-WebRequest "https://github.com/FiloSottile/mkcert/releases/download/v1.4.1/mkcert-v1.4.1-windows-amd64.exe" -UseBasicParsing -OutFile mkcert.exe | |
if ((Get-FileHash mkcert.exe).Hash -ne "1BE92F598145F61CA67DD9F5C687DFEC17953548D013715FF54067B34D7C3246") { | |
Remove-Item mkcert.exe -Force | |
throw "Invalid mkcert.exe file" | |
} | |
} | |
#Write-Host "Remove old TLS certificate..." -ForegroundColor Green | |
#Get-ChildItem -Path . -Include tls.crt -File -Recurse | foreach { $_.Delete()} | |
#Get-ChildItem -Path . -Include tls.key -File -Recurse | foreach { $_.Delete()} | |
Write-Host "Generating TLS certificate..." -ForegroundColor Green | |
& $mkcert -install | |
& $mkcert -cert-file D:\Install\tls.crt -key-file D:\Install\tls.key "*.$($hostName)" | |
#& $mkcert -key-file key.pem -cert-file cert.pem "*.$($HostName).localhost" | |
} | |
catch { | |
Write-Host "An error occurred while attempting to generate TLS certificate: $_" -ForegroundColor Red | |
} | |
finally { | |
Pop-Location | |
} | |
Write-Host "Done!" -ForegroundColor Green |
Once you run the script it will first download the mkcert.exe if not exist, and using that will create the Self-Signed Certificate.
Your directory will looks like below:
Method 2: Using PowerShell
Another way to create a self-signed certificate is by using PowerShell in-built 'New-SelfSignedCertificate' cmdlet. Here is an example of how to use this cmdlet to create a self-signed certificate:
Option 1: Creating a DNS based self-signed certificate
$workingFolder = "D:\Install" | |
$dnsNames = @("sunilcloudopsvm01","localhost","sunilcloudops.com") | |
$certFriendlyName = "Sitecore - Solr SelfSigned SSL Certificate" | |
$certPassword = "secret" | |
Write-Host "Looking for certificate $certFriendlyName" | |
$cert = Get-ChildItem -Path Cert:\LocalMachine\Root | where { $_.FriendlyName -eq $certFriendlyName } | |
if( $cert -eq $null ) | |
{ | |
$cert = New-SelfSignedCertificate -Subject $certFriendlyName -FriendlyName $certFriendlyName -DnsName $dnsNames -CertStoreLocation "cert:\LocalMachine\My" -NotAfter (Get-Date).AddYears(10) | |
Write-Host "Created certificate $($cert.Thumbprint)" | |
Move-Item "cert:\LocalMachine\my\$($cert.Thumbprint)" "cert:\LocalMachine\Root" | |
Write-Host "Moved cert to trusted store" | |
$cert = Get-Item "cert:\LocalMachine\Root\$($cert.Thumbprint)" | |
} | |
else | |
{ | |
Write-Host "Found certificate $($cert.Thumbprint)" | |
} | |
$certStore = "$workingFolder\solr-ssl.keystore.pfx" | |
$certPwd = ConvertTo-SecureString -String $certPassword -Force -AsPlainText | |
$cert | Export-PfxCertificate -FilePath $certStore -Password $certpwd | Out-Null | |
Write-Host "Exported Cert to $certStore" |
This command will create a self-signed certificate for the different hostnames and store it in the local certificate store.
Option 2: Creating a DNS + IP Address based self-signed certificate
$workingFolder = "D:\Install" | |
$dnsNames = "DNS=sunilcloudopssolr01&DNS=localhost" | |
$ip = "IPAddress=10.0.0.1&IPAddress=127.0.0.1" | |
$certFriendlyName = "Solr SelfSigned SSL Certificate" | |
$certPassword = "hmmmmmm" | |
Write-Host "Looking for certificate $certFriendlyName" | |
$cert = Get-ChildItem -Path Cert:\LocalMachine\Root | where { $_.FriendlyName -eq $certFriendlyName } | |
if( $cert -eq $null ) | |
{ | |
$cert = New-SelfSignedCertificate -Subject $certFriendlyName -FriendlyName $certFriendlyName -TextExtension @("2.5.29.17={text}$ip&$dnsNames") -CertStoreLocation "cert:\LocalMachine\My" -KeyAlgorithm RSA -KeyLength 2048 -NotAfter (Get-Date).AddYears(10) | |
Write-Host "Created certificate $($cert.Thumbprint)" | |
Move-Item "cert:\LocalMachine\my\$($cert.Thumbprint)" "cert:\LocalMachine\Root" | |
Write-Host "Moved cert to trusted store" | |
$cert = Get-Item "cert:\LocalMachine\Root\$($cert.Thumbprint)" | |
} | |
else {Write-Host "Found certificate $($cert.Thumbprint)"} | |
$certStore = "$workingFolder\solr-ssl.keystore.pfx" | |
$certPwd = ConvertTo-SecureString -String $certPassword -Force -AsPlainText | |
$cert | Export-PfxCertificate -FilePath $certStore -Password $certpwd | Out-Null | |
Write-Host "Exported Cert to $certStore" | |
Write-Host '' | |
Write-Host '2. Add the following lines to your solr.in.cmd:' -ForegroundColor Green | |
Write-Host '' | |
Write-Host "set SOLR_SSL_KEY_STORE=etc/solr-ssl.keystore.pfx" -ForegroundColor Yellow | |
Write-Host "set SOLR_SSL_KEY_STORE_PASSWORD=$certPassword" -ForegroundColor Yellow | |
Write-Host "set SOLR_SSL_TRUST_STORE=etc/solr-ssl.keystore.pfx" -ForegroundColor Yellow | |
Write-Host "set SOLR_SSL_TRUST_STORE_PASSWORD=$certPassword" -ForegroundColor Yellow | |
Write-Host '' | |
Write-Host 'Done!' |
This command will create a self-signed certificate for couple of domains and IP addresses and store it in the local certificate store.
If you want to have the Signer for the Self-Signed certificate then you can first generate the root certificate and then pass that root certificate while creating the other Self-Signed certificate.
$rootCert = New-SelfSignedCertificate -Subject 'CN=TestRootCA,O=TestRootCA,OU=TestRootCA' -KeyExportPolicy Exportable -KeyUsage CertSign,CRLSign,DigitalSignature -KeyLength 2048 -KeyUsageProperty All -KeyAlgorithm 'RSA' -HashAlgorithm 'SHA256' -Provider 'Microsoft Enhanced RSA and AES Cryptographic Provider'
New-SelfSignedCertificate -Subject $certFriendlyName -FriendlyName $certFriendlyName -Signer $rootCert -TextExtension @("2.5.29.17={text}$ip&$dnsNames") -CertStoreLocation "cert:\LocalMachine\My" -KeyAlgorithm RSA -KeyLength 2048 -NotAfter (Get-Date).AddYears(10)
Note: Self-signed certificates are not trusted by default and will not be recognized by default trusted root CA, so it is important to inform users that they are visiting a self-signed certificate website.
Thanks for reading, CloudOps ⌂Signing Off! 😊
No comments:
Post a Comment