This article explains how to generate a CSR using the OpenSSL CLI toolkit. We’ll go through a step-by-step guide to create a private key and a CSR. This should be helpful for system administrators and developers who need to set up secure connections for their servers or applications.
In the code samples, you can see how some undefined sausage is made, and it’s not pretty. But it works.
Background
When managing a website or a web application, it’s crucial to ensure secure data transmission and strong authentication. One essential aspect of web security is the use of SSL/TLS certificates to encrypt the communication between the client (web browser) and the server. These certificates are issued by trusted Certificate Authorities (CAs) and serve as a means of verifying the identity of the server to the client.
To obtain an SSL/TLS certificate from a CA, you need to create a Certificate Signing Request (CSR). A CSR is a block of encoded text that contains the information about the website and the certificate’s requester, including the public key that will be included in the certificate.
Running a SaaS solution for quite a few customers, occasionally there will be the need to generate new certificates and not all CAs have APIs that we could easily integrate with. That’s when generating CSRs manually comes in – and that’s what OpenSSL can help us with!
What is OpenSSL?
OpenSSL is an open-source toolkit consisting of a robust, full-featured open-source implementation of the Secure Sockets Layer (SSL) and Transport Layer Security (TLS) protocols. It’s widely used for securing communication on the internet and is available on various platforms, including Windows, Linux, and macOS.
OpenSSL provides a command-line interface (CLI) that allows users to perform various cryptographic operations, including generating private keys, creating CSRs, and managing certificates. The CLI is powerful, flexible, and versatile, making OpenSSL a popular choice for developers and system administrators working with SSL/TLS certificates.
OpenSSL’s CLI tooling is particularly useful for generating CSRs, which are essential for requesting SSL/TLS certificates from a CA. By using OpenSSL to create a CSR, you provide the necessary information to the CA, allowing them to issue a certificate that validates your website or web application’s identity and enables encrypted communication between the client and server.
And the CLI is exactly what we’ll use today! We’ll first show how to use it in PowerShell, and then take a step further and wrap it in a PowerShell function.
Solution
So here’s the script I whipped up. First, we’ll set a couple of variables:
# This is the Canonical Domain for the cert
$domain = 'intranet.contoso.com'
# organizational information
$subject = '/CN=$domain/O=Contoso/C=US/ST=New York/L=Contosoville'
# file name stub
$name = 'contoso'
# Subject Alternative Names, i.e. different subdomains we need to cover
$san = 'subjectAltName=DNS:7ef5df971b2746eaa427a6447c77b9e1-$domain,DNS:39df27aa95f14a23b3f68b231afcda82-$contoso,DNS:d60fa82a129a41a993ced784dcb217b0-$contoso,DNS:b3d13ef75ff84496a28381a742080aef-$contoso,DNS:8692efd9ec7c427cbd28d918dbb02ab7-$contoso,DNS:analytics-$contoso,DNS:3b9125a70e04472984e314f3dd99ed48-$contoso'
Okay. Setup is done. Please don’t ask too many questions – I make these notes for myself, after all 😉
Just replace the values – preferably, like, all of them, but the “name” names the smallest difference since it’s just file names – with ones you or your customer likes.
Now we can proceed with the actual creation.
openssl req -newkey rsa:2048 -keyout "$name.key" -out "$name.csr" -subj $subject -addext $san -passout pass:test
openssl rsa -in "$name.key" -out "$name.decrypted.key" -passin pass:test
You can also create a function somewhat like this:
function GenerateCSR($subject, $name, $san) {
openssl req -newkey rsa:2048 -keyout "$name.encrypted.key" -out "$name.csr" -subj $subject -addext $san -passout pass:test
openssl rsa -in "$name.encrypted.key" -out "$name.key" -passin pass:test
}
And then use it like this:
PS:> GenerateCSR '/CN=$domain/O=Contoso/C=US/ST=New York/L=Contosoville' 'contoso' 'subjectAltName=DNS:7ef5df971b2746eaa427a6447c77b9e1-intranet.contoso.com'
The script creates an unencrypted private key file ($name.key), so make sure to store it somewhere safe!
Verifying your private key and CSR match
Are you a little bit neurotic? Do you still want to double-check the private key and CSR we JUUUUST generated actually do match?
Well, do I have a solution for you! We can still use OpenSSL to do that, too – these 2 commands should produce the same result (highlighted in a screenshot below):
openssl req -noout -modulus -in ".\$name.csr"
openssl rsa -noout -modulus -in ".\$name.key"
And if you want to make it even more automated, you can do this:
(openssl rsa -noout -modulus -in ".\$name.key" | openssl md5) -eq (openssl req -noout -modulus -in ".\$name.csr" | openssl md5)
That should produce “True” 😀
And that’s all we had for today!
References
- https://www.ssl.com/faqs/how-do-i-confirm-that-a-private-key-matches-a-csr-and-certificate/
- “Performing cleanup” – Excel is stuck with an old, conflicted file and will never recover. - November 12, 2024
- How to add multiple app URIs for your Entra app registration? - November 5, 2024
- How to access Environment Secrets with GitHub Actions? - October 29, 2024