Saturday, January 14, 2023

Creating a Self-Signed Certificates for Secure Connections

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