Guide for newcomers to OpenSSL, including useful links, commands, and a comprehensive cheat sheet. In this article, you’ll find out what OpenSSL is, where to download it, learn basic security principles, and how to use OpenSSL to perform cryptographic operations.
What is OpenSSL?
OpenSSL is an open source crypto library that implements a variety of cryptography algorithms and SSL/TLS protocols to enable secure communication over the Internet and the exchange of data between network systems.
It’s been around for over 2 decades, thanks to its strong community support from around the world. As a result, OpenSSL is widely considered the number one choice for cryptographic purposes and internet security. In fact, OpenSSL is the backbone of the secure Internet as it helps protect millions of websites from eavesdropping.
The main features of this cryptography library are,
- Symmetric Encryption (or Secret Key Cryptography)
- Public Key Cryptography (or Asymmetric Cryptography)
- Key Agreement
- Certificate Handing
- Pseudo-Random Number Generator
- Message Authentication Code (MAC)
- Hash Message Authentication Code (HMAC)
- Key Derivation Function (KDF)
We will discuss these features in the upcoming sections with examples to help you better understand the different utilities and crypto functions of this library.
In addition to providing implementations for the popular protocols like SSL (Secure Sockets Layer) and TLS (Transport Layer Security), OpenSSL provides a feature-rich command line tool that is widely used primarily by developers, network administrators, and security experts to ease the tasks such as,
- generating private keys or keypair (private key and csr) combination
- producing csr and decoding
- creating self-signed certificates using certificate utility (x509)
- bundling private key and certificate
- reading cert and/or private key from keystore (e.g. pkcs12)
- making certificate chain
- computing hash digest (or hash values)
- decoding signatures using ans1parse
- signing and validating messages
- encrypting and decrypting messages
- analyzing and debugging secure communication, and so on….
While the library offers a variety of cryptographic functions that you can bundle together to perform operations in your application, there are many third-party vendors that use this library with additional customization for use in hardware security modules to offload the crypto processing. A Hardware Security Module (or HSM) is basically a physical device (or appliance) that provides enhanced security for digital keys and cryptographic operations.
OpenSSL is a popular, efficient and widely used cryptographic toolkit for securing network communication. Because security is the most serious issue to consider, protecting internet traffic between systems is the top priority. In fact, the majority of web servers use the OpenSSL implementation of SSL/TLS protocols to protect their websites and secure end-to-end communication.
You can run OpenSSL on some popular Unix-based operating systems like Linux, CentOS, macOS as well as Microsoft Windows. Here, you will find the link to download the latest version of OpenSSL installation packages for Windows.
If you want to compile the code yourself, you can download the OpenSSL library source code from the GitHub website. Note, despite the fact that the OpenSSL core library is built in the C programming (low-level) language, one can use wrappers to integrate this library into many other computer languages.
But if dealing with source code compilation, especially C code, isn’t the kind of work you want to get into, you can skip it. Instead, head straight to this webpage where you can find the OpenSSL distributable for Windows and other operating systems. Here, you will find several options to download OpenSSL binaries compiled and distributed by a group of people.
Among them, if you visit the slproweb.com, you will notice that there are two types of Windows installers for each version of OpenSSL, lite mode installer (package size is merely 5MB) is recommended for general users while the full mode installer is specifically designed for use by software developers and includes advanced tools and libraries.
Install OpenSSL on Windows
Next, we’re going to install OpenSSL using the installer package downloaded in the previous section.
Run the installer (MSI or EXE) file and follow the onscreen instructions. Here, I would want you to pay attention to the screen where it will ask you to make a choice.
Copy OpenSSL DLLs to:
- The Windows system directory
- The OpenSSL binaries (/bin) directory
Once the installation is complete, open the command prompt and type
openssl version and hit enter. If it displays the version information, it means that you have installed it correctly.
Configure OpenSSL (Config file)
OpenSSL can read its settings from configuration file (INI). Use config library to read default settings from config file for openssl commands. This can be quite handy when you need to supply different arguments to different commands, and use one configuration for all.
When installed, this file is stored by default into the same directory where binary files are located – usually in the bin directory. However, if you wish to copy it to another location, you can easily override the config path by setting the OPENSSL_CONF environment variable.
Open a new
cmd as administrator and run the following command:
Public Key Cryptography
Generating a Private Key using OpenSSL
To create a new private key, you will use the
openssl genrsa command. This command generates the private key of the size specified in the argument. By default, OpenSSL uses the RSA algorithm for public key encryption with a default key length of 1024. To override the size, you can either put 2048 or 4096 (represents size in bits).
openssl genrsa -out yourprivatekey.pem 2048
The command we ran above computes a unique RSA private key (or public-private key pair) of 2048 bits, which is equivalent to 256 bytes.
Now that your key pair has been generated, you can read your private key using OpenSSL. To view (or display textual representation of) the private key part, run the
openssl rsa command providing the RSA private key as an argument.
openssl rsa -in yourprivatekey.pem
Note, you should always secure your private key with a passphrase and only limited users should have access to it. Therefore, we recommend not executing the above command in front of an unintended audience or users.
To print the public key part, run the same command again with just one argument
pubout. It will instruct OpenSSL to output only the public key.
openssl rsa -in yourprivatekey.pem -pubout
To dump the public key part to a separate file, run the command below.
openssl rsa -in yourprivatekey.pem -pubout -out yourpublickey.pem
Creating a CSR (Certificate Signing Request) with OpenSSL
A CSR, an acronym for Certificate Signing Request, is an encoded file (or content) that contains some basic information about the entity that wishes to obtain a digital certificate from the certificate authority of the public key infrastructure. The certificate authority decodes the signing request to view the content to identify the certificate requester – such information usually includes the organization name, common name (domain name), region and country. In addition to that, the request also includes the public key.
There are two methods to generate a CSR,
- Use an existing private key to generate a new CSR, or
- Generating a new pair of csr and private key together
Method 1: Generate a new CSR using an existing Private Key
When creating a new CSR, you can reuse an existing private key. The
openssl req command is used to generate a new csr from the private key we created in the previous section.
openssl req –key yourprivatekey.pem –new –out yourcert.csr
To view the content of your csr, run the command below.
openssl req -in yourcert.csr -noout -text
Method 2: Generate a new CSR and a Private Key
It’s always recommended to create a new key pair each time you renew your certificate. Whether you create a key and csr individually (as explained above) or combined (as explained below).
openssl req command can also generate a combination of the key and the csr with a single command.
openssl req –newkey rsa:2048 –nodes –keyout yourprivatekey.pem –new –out yourcert.csr
After generating the CSR, send it to a certificate authority for signing.
In general, depending on the type of certificate request, it can take anywhere from a few hours to a day or a week for the CA to verify that the requester is a legitimate individual or company.
Generating a Self-Signed Certificate (Without CA)
After you generate a CSR (Certificate Signing Request), you can send it to a Certificate Authority, such as Entrust, who will first verify your (as a requestor) identity and later issue a signed certificate.
What is a Self-Signed Certificate?
A digital certificate is a file that contains the identity of a user or device and is primarily used to secure network communication and/or verify ownership. Such a file is usually issued by the trusted certificate authority to establish trust among users.
A self-signed certificate, on the other hand, is a certificate that is manually signed rather than signed by a trusted certificate authority. Normally, this type of certificate is used in low-risk internal networks or in the development phase of the product or application.
There are (at least) two different ways to create a self-signed certificate. One is using
openssl req command through which we can generate new private key and new certificate together.
To create a new rsa private key and self-signed certificate,
openssl req -x509 -sha256 -nodes -days 365 -newkey rsa:2048 -keyout yourprivatekey.pem -out yourcert.pem
Another way to produce a self-signed certificate is to use the
openssl x509 utility which you can use to generate a certificate from an existing certificate sing request.
To create a self-signed certificate from an existing csr (certificate request) and private key,
openssl x509 -req -days 365 -sha256 -in yourcert.csr -signkey yourprivatekey.pem -out yourcert.pem
Asymmetric Cryptographic Operations
1. Computing a Signature using RSA Private Key and Verification
We have explained above the hashing technique and some digest functions that are widely used to calculate message digests.
openssl dgst command is mainly used to,
- compute the message digest of the supplied input or file(s), as well as
- generate and verify a digital signature using message digest (but no more than 1 file)
To compute the message digest of an input file (e.g. data.txt) and then generate a digital signature of the computed digest using a private key, run the command below:
openssl dgst -sha256 -binary -sign yourprivatekey.pem -out data.rsasha256 data.txt
openssl dgst command when executing in combination with the
-sign option will sign (actually encrypt) the digest using the private key and store the result in the output file i.e. data.rsasha256 in binary format. Alternatively, you can use -hex option to output as a hex dump. The output file, or signature generated, is actually based on the RSA PKCS#1 v1.5 scheme which is the first in the family of standards known as the Public Key Cryptography Standard.
Next, to validate the signature using public key, use the command like below:
openssl dgst -sha256 -verify yourpublickey.pem -signature data.rsasha256 data.txt
Do remember that you can supply one or more files as input when computing a digest, however, the signing (-sign) and verification (-verify) options should only be used when a single file is being signed or verified. Another important thing is that you can only validate binary signatures using openssl. Signatures encoded in hex cannot be verified directly. Therefore, you must convert it to binary form before validation either using
openssl xxd -r option or any other way.
When signing a message, it requires a private key. This process involves computing a message digest and then encrypting it using the private key. The
dgst command determines the algorithm (RSA or ECC or any other) to use for signing based on the ASN.1 info in the private key. On the other hand, verification can handle either RSA or DSA or ECDSA signature. The signature generated using the
dgst command does not have the associated data to identify the signer and the algorithm used such as in other cryptographic formats: CMS or S/MIME.
2. Generating a Bundled PKCS#7 Signature and Verification
Before you can generate a PKCS#7 signature, you will need a private key and a certificate. The certificate is used to attach the signer’s information to the signature which guarantees the authenticity of the signed document.
Let’s start by understanding what PKCS#7 is. PKCS#7, or its successor, CMS, is a widely adopted cryptographic standard from the PKCS (Public Key Cryptography Standards) family. It is mainly used to digitally sing a message, compute a digest, authenticate or even encrypt digital data of any form (text or binary).
What is a bundled PKCS#7 signature?
In the previous example, we learned how to compute an RSA signature which can encapsulate both the data and the raw signature (encrypted hash) which is actually a kind of bundled (but incomplete, I would say) signature. However, there are several known problems with such signatures.
The issues with such a signature are,
- No proof of authenticity of the document or its origin
- One can deny a claim to have sent or received a signed document
The only assurance you can claim is integrity – if any changes were made to the document – after signing it.
To deal with those issues, different standards have emerged and PKCS#7 is one of them.
PKCS#7 has several different content types. Among them, PKCS#7 SignedData has native capabilities to store (or encapsulate) the digital signature (thus the encrypted hash), information about the signer which is usually the subject name of the issuer of the signer’s digital certificate along with the serial number, as well as the original (or signed) data. This form of encapsulation, which bundles the raw signature, data and other useful signer information, is sometimes referred to as PKCS#7 bundled signature. Often the term is used interchangeably with an embedded signature.
openssl cms utility can be used to generate a bundled PKCS#7 digital signature. To create a bundle (or opaque) signature, use the command below which uses a certificate and private key, and store the result (S/MIME format) in the output file.
openssl cms -sign -in data.txt -out data.signed.nodetached.msg -signer yourcert.pem -inkey yourprivatekey.pem -nodetach
Note that here the
-nodetach option bundles the data to the output S/MIME signed file.
To verify a bundled PKCS#7 signature against a given certificate of the signer, run the command with
openssl cms -verify -in data.signed.nodetached.msg -signer signercert.pem -out data.out.txt
If the verify command runs successfully, it will extract the signed data to an output file and the signer’s certificate to a certificate file, respectively.
Hint: to successfully verify a digital signature generated using a self-signed certificate, supply the extra option
-noverify which will skip the certificate verification. (Only use this trick in LAB or DEV environment)
3. Creating and Verifying a PKCS#7 Detached Signature (Omit Payload)
As the name suggests, a detached signature refers to a method of creating a signature without actually embedding the original data. Detached signatures are commonly used to verify a signed file such as software or executable files.
We can drop the
-nodetach flag from the previous example that would allow you to generate a PKCS#7 signature in a detached mode.
openssl cms -sign -in data.txt -out data.signed.detached.msg -signer yourcert.pem -inkey yourprivatekey.pem
Note that verification of a detached signature typically requires an input file to the
-verify command that contains detached content. The
-content option is used with the
-verify command when a signature is in a detached form.
openssl cms -verify -in data.signed.detached.msg -signer signercert.pem -content data.txt
During the signature verification process, the hash of the content file is matched against the decrypted signature (hash in PKCS#7 container) to verify the integrity of the message.
4. Encrypt and Decrypt a PKCS#7 document
Before you can encrypt a file, you must have a public key part of the key pair of your peer for whom you are going to encrypt a message.
In the example below, we are using the same cms utility that we used earlier to calculate a signed PKCS#7 message (S/MIME type). However, to encrypt a message, we use the
-encrypt option and supply the recipient’s certificate with the
-recip command option.
openssl cms -encrypt -in data.txt -out data.encrypted.msg -recip recipientcert.pem
As you run this command, it will produce an encrypted message file for the recipient.
Now imagine a scenario when you want to encrypt a message for multiple recipients. In this case, you use the
-recip option multiple times, each representing a unique recipient certificate. (for example, -recip recipient1cert.pem -recip recipient2cert.pem)
To decrypt a pkcs#7 file that we encrypted above, run the command below:
openssl cms -decrypt -in data.encrypted.msg -inkey yourprivatekey.pem -out data.out.txt
Note, when decrypting a message, you can specify the recipient certificate. The certificate must match one of the recipients of the message otherwise openssl would report an error.
5. Create a Bundled Signature and Envelope (or encrypt) in a PKCS#7 document
In PKCS#7, SignedData supports attached and detached signature formats. But sometimes depending on the data being signed, you may actually have a need to protect the content of the message that is being signed for confidential purposes.
Below we have combined the two commands that first produce a pkcs#7 detached signature and then encrypt the signature using the triple DES encryption algorithm for the recipient, as supplied with recipientcert.pem, to generate a pkcs#7 enveloped document.
openssl cms -sign -in data.txt -signer yourcert.pem -inkey yourprivatekey.pem | openssl cms -encrypt -out data.encrypted.signed.detached.msg -from [email protected] -to [email protected] -subject "subject line" -des3 recipientcert.pem
The output from the above command will produce a bundled pkcs#7 signature that is later encrypted using the supplied encryption algorithm.
Let’s break the above command,
- first, that would produce a signature, and then
- encrypt signature and signed data
In the first step, we generate a PKCS7 signature that encloses the signed data.
openssl cms -sign -in data.txt -out data.signed.detached.msg -signer yourcert.pem -inkey yourprivatekey.pem -nodetach
Next, a signed PKCS#7 message is encrypted, resulting in another PKCS#7 enveloped message.
openssl cms -encrypt -in data.signed.detached.msg -out data.encrypted.signed.detached.msg -from [email protected] -to [email protected] -subject "subject line" -des3 recipientcert.pem
6. Decrypting a PKCS#7 document and Verifying a Bundled Signature
To decrypt the message, you need to use the private key. In the example below, we provide the encrypted signed pkcs#7 file as an input.
openssl cms -decrypt -in data.encrypted.signed.detached.msg -inkey yourprivatekey.pem -out data.signed.detached.out.msg
The command writes the decrypted content to the output file.
Next, to verify the signature, we use decrypted file as an input and use the signer’s certificate to validate the signed pkcs#7 document.
openssl cms -verify -in data.signed.detached.out.msg -signer signercert.pem -content data.txt
Note, the content file is optional.
Below we have combined the two operations, decrypt and verify the signature.
openssl cms -decrypt -in data.encrypted.signed.detached.msg -inkey yourprivatekey.pem | openssl cms -verify -signer signercert.pem
What is Public Key Infrastructure (a.k.a. PKI)?
Public Key Infrastructure defines roles and policies to manage the creation, renewal, and revocation of digital certificates that help establish unique digital identities for users, devices, and applications – in order to secure network communication and verifying the authenticity of digital messages.
To learn how PKI operates, check out this article.
How to Import Certificate and Private Key into PKCS#12 file?
A PKCS#12 is a secure container that bundles your private key and certificates. The file can be easily identified by its extension, .pfx or .p21. It’s mainly used to store, protect and transfer information.
To bundle a certificate and private key and store them in a single file, use the
openssl pkcs12 command with the -export option as shown below.
openssl pkcs12 -export -inkey yourprivatekey.pem -in yourcert.pem -out keycert.p12
When you run the above command, you will be prompted for a password to protect your private key in the pkcs#12 file. This password will be required each time you need to read the certificate, private key or any other cryptographic object such as the CRL stored in the pfx or p12 file.
To view the content of pkcs#12 file including private key, run the command with
openssl pkcs12 -in keycert.p12 -nodes
This will display the private key without encryption.
How Do I Check if the CSR and/or Certificate matches the Private Key?
Are you looking for a way to check if the private key corresponds to the CSR or the certificate? Will, you have come to the right place.
In layman’s terms, if you ever parse a certificate or CSR file and then compare it to the contents of the private key, it will never look identical or even close to comparable. However, they each have one thing in common called a public key that sticks them together.
To extract the public key part from the private key,
openssl pkey -in yourprivatekey.pem -pubout -outform pem
Next, extract the same thing from the certificate,
openssl x509 -in yourcert.pem -pubkey -noout -outform pem
And then retrieve the public key from the csr (certificate singing request),
openssl req -in yourcert.csr -pubkey -noout -outform pem
Now compare the output of the three commands.
If the certificate and csr files were created from the same private key, the public key part should be identical in all three files.
Another quick and efficient way to match the certificate, csr with private key is by computing the hash of the public key part. You can do so by pipe the output (public key) from the command to
openssl md5 to compute the hash.
openssl pkey -in yourprivatekey.pem -pubout -outform pem | openssl md5
Hash (or message digest) values computed using the same digest algorithm can be compared for equality. So, if the hashes of the above three commands match it would mean that they all have the same public key.
Technically you can use any message-digest algorithm to calculate the hash, but you must use the same one in the commands or the hash values would not be comparable.
A third way to compare them would be to use the modulus part as shown in the example below.
openssl rsa -noout -modulus -in yourprivatekey.pem | openssl md5 openssl x509 -noout -modulus -in yourcert.cer | openssl md5 openssl req -in yourcert.csr -noout -modulus | openssl md5
How Can I Verify if the Certificate and Private Key match in PKCS#12 file?
PKCS#12 is a type of container that can contain different cryptographic information. It’s defined in terms of several “bag” structures where each bag can contain different information such as private key, cert, crl, etc.
But sometimes you can mistakenly put the wrong certificate and private key in it, which could affect signing and/or encryption operations.
To verify if you have bundled the matching certificate and private key into your pkcs#12 file, perform the steps in order below.
First, export private key from your pkcs#12 file,
openssl pkcs12 -in keycert.p12 -nodes -nocerts -out yourprivatekey.pem
Next, export certificate from your pkcs#12 file,
openssl pkcs12 -in keycert.p12 -nodes -nokeys -out yourcert.pem
After successfully exporting the certificate and private key, you can confirm that the private key matches the certificate by comparing the public key part as explained above.
What is CSR? How Do I Create a new Certificate Request from an existing Certificate using a Private Key?
If you’ve ever wondered what CSR looks like but couldn’t get a clear answer, well, today is a lucky day!
A CSR (Certificate Signing Request) is basically a form of request that is usually created by the end user using the private key and sent to CA (Certificate Authority) who then verifies the identity of the requestor before issuing the digital certificate.
How does a CSR look?
Below is an example of a certificate signing request:
openssl asn1parse -in yourcert.csr -inform pem
Here, we used the openssl asn1parse command to parse the csr file content. Like the digital certificate, csr also uses ASN.1 notation.
Another way to parse the contents of the csr file is to use the openssl req command which can print the contents as much more readable and user-friendly text.
openssl req -in yourcert.csr -noout -text
CSR will include the following critical information:
- Subject – refers to the name of the user or device to which the certificate authority issues the certificate.
- Public Key – is used to confirm the identity and secure the communication by the encryption method.
- Signature Algorithm – to be used to sign the certificate.
How to generate a CSR (or Certificate Request) from an existing Certificate?
Typically, you generate a CSR with a new private key as a combination of key pairs. However, sometimes you just want to create a signing request from an existing certificate.
Imagine a situation where, for technical reasons, you want to generate a new CSR using the properties of the old or previously signed certificate. This is where the
openssl x509 command comes in handy. With the use of the
-x509toreq option, you can produce a CSR from an existing signed certificate inheriting all DN (Distinguished Name) field values.
In the example below, we produce a new CSR by copying all the distinguished name field values:
openssl x509 -x509toreq -in yourcert.pem -signkey yourprivatekey.pem -out newcert.csr
Disclaimer: This post may include affiliate links. If you click one of them, we may receive a small commission at no extra cost to you. Thank you for your support.