chore(openssl): vastly improve snippets

This commit is contained in:
Michele Cereda
2024-05-31 01:37:00 +02:00
parent 64ed0c562a
commit 23d33a0f87
2 changed files with 236 additions and 47 deletions

View File

@@ -9,7 +9,7 @@
1. [Code 20: unable to get local issuer certificate](#code-20-unable-to-get-local-issuer-certificate)
1. [Code 21: unable to verify the first certificate](#code-21-unable-to-verify-the-first-certificate)
1. [Further readings](#further-readings)
1. [Sources](#sources)
1. [Sources](#sources)
## TL;DR
@@ -118,11 +118,12 @@ openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -days 365
To make it **not** ask for a password, add the `-nodes` option.
To avoid answering the questions (for automation), add `-subj "/C=US/ST=Oregon/L=Portland/O=Company Name/OU=Org/CN=www.example.com"`:
To avoid answering the questions (for automation), add
`-subj "/C=US/ST=Oregon/L=Portland/O=Company Name/OU=Org/CN=www.example.com"`:
```sh
$ openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -days 365 -nodes -subj "/C=NL/ST=Nederlands/L=Amsterdam/O=Mek Net/OU=Org/CN=mek.info"
openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -days 365 -nodes -subj "/C=NL/ST=Nederlands/L=Amsterdam/O=Mek Net/OU=Org/CN=mek.info"
$ openssl req -x509 -out 'cert.pem' \
-newkey 'rsa:4096' -keyout 'key.pem' -days '365' -nodes -subj "/C=NL/ST=Nederlands/L=Amsterdam/O=Mek Net/OU=Org/CN=mek.info"
Generating a 4096 bit RSA private key
..............................................................................................................................................................................................................................++
...........................................................................................................................................................................++
@@ -181,17 +182,21 @@ closed
See also [OpenSSL unable to verify the first certificate for Experian URL] and [Verify certificate chain with OpenSSL].
One or more certificates in the certificate chain is not valid, self-signed or simply was not provided by either the server or the client (if a client certificate is needed).<br />
This could also mean that the root certificate is not in the local database of trusted root certificates, which could have been not given to, or queried by, OpenSSL.
One or more certificates in the certificate chain is not valid, self-signed or simply was not provided by either the
server or the client (if a client certificate is needed).<br />
This could also mean that the root certificate is not in the local database of trusted root certificates, which could
have been not given to, or queried by, OpenSSL.
A well configured server sends the entire certificate chain during the handshake, therefore providing all the necessary intermediate certificates; servers for which the connection fails might be providing only the end entity certificate.
A well configured server sends the entire certificate chain during the handshake, therefore providing all the necessary
intermediate certificates; servers for which the connection fails might be providing only the end entity certificate.
OpenSSL is **not** capable of getting missing intermediate certificates on-the-fly, so a `s_client -connect` attempt could fail where a full-fledge browser, able to discover certificates, would succeed on the same URL.
OpenSSL is **not** capable of getting missing intermediate certificates on-the-fly, so a `s_client -connect` attempt
could fail where a full-fledge browser, able to discover certificates, would succeed on the same URL.
You can:
- either make the server send the entire certificate chain
- or pass the missing certificates to OpenSSL as client-side parameters using the '-CApath' or '-CAfile' options.
- Either make the server send the entire certificate chain, or
- Pass the missing certificates to OpenSSL as client-side parameters using the '-CApath' or '-CAfile' options.
### Code 21: unable to verify the first certificate
@@ -208,28 +213,26 @@ See [code 20](#code-20-unable-to-get-local-issuer-certificate).
- [Display the contents of a SSL certificate]
- [Check SSL certificate chain with OpenSSL examples]
## Sources
All the references in the [further readings] section, plus the following:
### Sources
- [How to generate a self-signed SSL certificate using OpenSSL]
- [OpenSSL unable to verify the first certificate for Experian URL]
- [Verify certificate chain with OpenSSL]
- [How to put domain correctly in CSR?]
- [OpenSSL command cheatsheet]
<!--
References
Reference
═╬═Time══
-->
<!-- In-article sections -->
[further readings]: #further-readings
<!-- Others -->
[check ssl certificate chain with openssl examples]: https://www.howtouselinux.com/post/certificate-chain
[create a self signed certificate]: https://stackoverflow.com/questions/10175812/how-to-create-a-self-signed-certificate-with-openssl#10176685
[display the contents of a ssl certificate]: https://support.qacafe.com/knowledge-base/how-do-i-display-the-contents-of-a-ssl-certificate/
[how to generate a self-signed ssl certificate using openssl]: https://stackoverflow.com/questions/10175812/how-to-generate-a-self-signed-ssl-certificate-using-openssl#10176685
[how to put domain correctly in csr?]: https://www.namecheap.com/support/knowledgebase/article.aspx/9641/2290/how-to-put-domain-correctly-in-csr/
[openssl command cheatsheet]: https://www.freecodecamp.org/news/openssl-command-cheatsheet-b441be1e8c4a
[openssl commands to check and verify your ssl certificate, key and csr]: https://www.ibm.com/support/pages/openssl-commands-check-and-verify-your-ssl-certificate-key-and-csr
[openssl unable to verify the first certificate for experian url]: https://stackoverflow.com/questions/7587851/openssl-unable-to-verify-the-first-certificate-for-experian-url
[the most common openssl commands]: https://www.sslshopper.com/article-most-common-openssl-commands.html

View File

@@ -1,41 +1,227 @@
#!/usr/bin/env sh
# Generate pseudo-random passwords.
openssl rand 32
openssl rand -base64 18
# Generate certificate signing requests.
# '-nodes' leaves the output files unencrypted.
openssl req -new -out 'gitlab.mine.info.csr' -newkey 'rsa:2048' -keyout 'gitlab.mine.info.new.key' # also create a key
openssl req -new -out 'gitlab.mine.info.csr' -key 'gitlab.mine.info.existing.key' # use existing keys
openssl req -new -out 'gitlab.mine.info.csr.pem' -config 'csr.conf' -days '365' -sha256
##
# Passwords
##
# Verify certificate signing requests and print the data given in input on creation.
openssl req -text -noout -verify -in 'gitlab.mine.info.csr'
# Generate pseudo-random passwords
openssl rand '32'
openssl rand -base64 '18'
# Check existing keys and verify their consistency.
openssl rsa -check -in 'gitlab.mine.info.new.key'
# Generate self-signed certificates.
openssl req -x509 -out 'self-signed.certificate.pem' \
-newkey 'rsa:4096' -keyout 'self-signed.private.key' \
-subj '/C=US/ST=Oregon/L=Portland/O=Company Name/OU=Org/CN=www.company.com' \
-days '365' -sha256
##
# Private keys
##
# Check certificates or keys and return information about them.
# Generate RSA keys
openssl genrsa -out 'rsa4096.key' '4096'
openssl genrsa -out 'rsa8192.key' '8192'
# Generate RSA keys encrypted with passphrases based on AES CBC 256
openssl genrsa -aes256 -out 'rsa4096.withPassphrase.key' '4096'
# Generate ECDSA keys
# Supported curves: prime256v1, secp384r1, secp521r1, others
openssl ecparam -genkey -name 'secp521r1' | openssl ec -out 'ec521.key'
# List available EC curves
openssl ecparam -list_curves
# Print out key information
openssl rsa -in 'rsa.key' -pubout # public key
openssl rsa -in 'rsa.key' -noout -modulus # modulus
# Print out key information
# Textual representation of components
openssl rsa -in 'rsa.key' -text -noout
openssl ec -in 'ec.key' -text -noout
# Check keys and verify their consistency.
openssl rsa -check -in 'private.key'
# Remove passphrases from keys
openssl rsa -in 'withPassphrase.key' -out 'plain.key'
# Encrypt existing keys with passphrases
openssl rsa -des3 -in 'plain.key' -out 'withPassphrase.key'
# Generate Diffie-Hellman params with given lengths (in bits)
openssl dhparam -out 'dhparams.pem' '2048'
##
# Certificate Signing Requests (CSR)
# ----------------------------------
# Digests must be names of supported has functions (md5, sha1, sha224, sha256, sha384, sha512, …)
##
# Create CSRs from existing private keys
openssl req -new -key 'private.key' -out 'request.csr'
openssl req -new -key 'private.key' -out 'request.csr' -sha512
# Create CSRs *and* their private keys
# '-nodes' leaves the output file unencrypted
openssl req -nodes -newkey 'rsa:4096' -keyout 'private.key' -out 'request.csr'
openssl req -new -newkey 'rsa:2048' -keyout 'private.key' -out 'request.csr'
# Provide CSR subject information non-interactively
# => on the CLI rather than through interactive prompt
openssl req -nodes -newkey 'rsa:8192' -keyout 'private.key' -out 'request.csr' \
-subj "/C=UA/ST=Kharkov/L=Kharkov/O=Super Secure Company/OU=IT Department/CN=example.com"
# Create CSRs from existing certificates and private keys
openssl x509 -x509toreq -in 'certificate.pem' -out 'request.csr' -signkey 'private.key'
# Generate CSRs for multi-domain SAN certificates by supplying OpenSSL config files
openssl req -new -key 'private.key' -out 'request.csr' -config 'request.conf'
openssl req -new -out 'certificate.pem' -config 'csr.conf' -days '365' -sha256
# with 'request.conf' being:
# [req]prompt=nodefault_md = sha256distinguished_name = dnreq_extensions = req_ext
# [dn]CN=example.com
# [req_ext]subjectAltName=@alt_names
# [alt_names]DNS.1=example.comDNS.2=www.example.comDNS.3=ftp.example.com
# Verify CSR signatures
openssl req -in 'request.csr' -verify
openssl req -in 'request.csr' -verify -text -noout # prints the data given in input during creation
##
# X.509 certificates
##
# Create self-signed certificates with their new private key from scratch
openssl req -nodes -newkey 'rsa:2048' -keyout 'private.key' -out 'certificate.crt' -x509 -days '365'
openssl req -newkey 'rsa:4096' -keyout 'private.key' -out 'certificate.pem' -x509 -days '365' -sha256 \
-subj '/C=US/ST=Oregon/L=Portland/O=Company Name/OU=Org/CN=www.company.com'
# Create self-signed certificates using existing CSRs and private keys
openssl x509 -req -in 'request.csr' -signkey 'private.key' -out 'certificate.crt' -days '365'
# Sign child certificates using one's own CA certificates and their private keys
# Very naive example of how to issue new certificates should one be a CA company
openssl x509 -req -in 'child.csr' -days '365' -CA 'ca.crt' -CAkey 'ca.key' -set_serial '01' -out 'child.crt'
# Print out certificate information
openssl x509 -in 'certificate.crt' -text -noout # textual representation of components
openssl x509 -in 'certificate.crt' -fingerprint -sha256 -noout # fingerprint as sha256 digest
openssl x509 -in 'certificate.crt' -fingerprint -md5 -noout # fingerprint as md5 digest
# Verify certificate chains
# If a certificate is its own issuer, it is assumed to be the root CA (needs to be self signed)
openssl verify 'certificate.crt' # root and *all* intemediate certificates need to be trusted by the local machine
openssl verify -untrusted 'intermediate-ca-chain.pem' 'certificate.crt' # the root certificate need to be trusted by the local machine
openssl verify -CAFile 'root.crt' -untrusted 'intermediate-ca-chain.pem' 'child.crt'
# Verify certificates served by remote servers cover the given hostnames
# Checks mutlidomain certificates properly cover all the hostnames
# All the certificates (including the intermediate ones) should be displayed
# CA certificates bundle on Linux: '/etc/ssl/certs/ca-certificates.crt'
# '-servername' is used to specify a domain for multi-domain servers
openssl s_client -verify_hostname 'www.example.com' -connect 'example.com:443'
openssl s_client -connect 'www.google.com:443' -showcerts -CAfile 'ca/certificates/bundle.crt'
openssl s_client -connect 'www.google.com:443' -showcerts -CApath '/etc/ssl/certs'
# Convert certificate between DER and PEM formats
openssl x509 -in 'certificate.pem' -outform 'der' -out 'certificate.der'
openssl x509 -in 'certificate.der' -inform 'der' -out 'certificate.pem'
# Combine certificates into PKCS7 (P7B) files
openssl crl2pkcs7 -nocrl -certfile 'child.crt' -certfile 'ca.crt' -out 'example.p7b'
# Convert from PKCS7 to PEM
# If PKCS7 files have multiple certificates, the reulting PEM files will contain all of the items from the PKCS7 files.
openssl pkcs7 -in 'example.p7b' -print_certs -out 'example.crt'
# Combine PEM certificate files and private keys to PKCS#12 (.pfx .p12)
# One can add chains of certificates to PKCS12 files.
openssl pkcs12 -export -out 'certificate.pfx' -inkey 'private.key.pem' -in 'certificate.pem' -certfile 'ca-chain.pem'
# Convert PKCS#12 files (.pfx .p12) containing private keys and certificates to PEM
openssl pkcs12 -in 'keystore.pfx' -out 'keystore.pem' -nodes
##
# TLS client
# --------------------------------------
##
# Tests connections to remote servers
openssl s_client -connect 'www.google.com:443'
openssl s_client -host 'www.google.com' -port '443'
# Show the full certificate chains
openssl s_client … -showcerts < '/dev/null'
# Extract certificates
openssl s_client … 2>&1 < '/dev/null' | sed -n '/-----BEGIN/,/-----END/p' > 'certificate.pem'
# Override SNI (Server Name Indication) extension with other server names
# Allows testing multiple secure sites hosted by same IP address
openssl s_client … -servername 'host.fqdn'
# Test TLS connections by forcibly using specific cipher suites
# Checks if servers can properly talk via different configured cipher suites
openssl s_client … -cipher 'ECDHE-RSA-AES128-GCM-SHA256' 2>&1 < '/dev/null'
# Measure SSL connection time without and with session reuse
openssl s_time -connect 'example.com:443' -new
openssl s_time -connect 'example.com:443' -reuse
# Roughly examine TCP and SSL handshake times using `curl`
curl -kso '/dev/null' -w "tcp:%{time_connect}, ssldone:%{time_appconnect}\n" 'https://example.com'
##
# Others
##
# Verify private keys match certificates and CSRs
openssl rsa -noout -modulus -in 'private.key' | openssl sha256
openssl req -noout -modulus -in 'request.csr' | openssl sha256
openssl x509 -noout -modulus -in 'certificate.crt' | openssl sha256
# Check certificates or keys and return information about them
openssl x509 -text -noout -in 'certificate.crt'
openssl rsa -text -noout -in 'private.key'
# Verify certificate chains.
# If a certificate is its own issuer, it is assumed to be the root CA.
# This means the root CA needs to be self signed for 'verify' to work.
openssl verify -CAfile 'RootCert.pem' -untrusted 'Intermediate.pem' 'UserCert.pem'
# Calculate digests
openssl dgst -md5 < 'input.file'
cat 'input.file' | openssl md5
openssl dgst -sha1 < 'input.file'
cat 'input.file' | openssl sha1
openssl dgst -sha512 < 'input.file'
cat 'input.file' | openssl sha512
# Check SSL connections.
# All the certificates (including the intermediate ones) should be displayed.
# CA certificates bundle on Linux: '/etc/ssl/certs/ca-certificates.crt'.
# '-servername' is used to specify a domain for multi-domain servers.
openssl s_client -connect 'www.google.com:443' -showcerts
openssl s_client -connect 'www.google.com:443' -showcerts -servername 'host.fqdn'
openssl s_client -connect 'www.google.com:443' -showcerts -CAfile 'ca/certificates/bundle.crt'
openssl s_client -connect 'www.google.com:443' -showcerts -CApath '/etc/ssl/certs'
# Base64 encoding and decoding
cat /dev/urandom | head -c 50 | openssl base64 | openssl base64 -d
# Measure speed of security algorithms
openssl speed 'rsa2048'
openssl speed 'ecdsap256'
# List available TLS cipher suites
openssl ciphers -v
# Enumerate individual cipher suites
# Described by a short-hand OpenSSL cipher list string.
# Useful to test 'ssl_ciphers' string.
openssl ciphers -v 'EECDH+ECDSA+AESGCM:EECDH+aRSA+SHA256:EECDH:DHE+AESGCM:DHE:!RSA!aNULL:!eNULL:!LOW:!RC4'
##
# Check certificate revocation status from OCSP responders
# --------------------------------------
# Multi-step process:
# 1. Retrieve the certificate from a remote server
# 2. Obtain the intermediate CA certificate chain
# Use '-showcerts' to show the full certificate chain, and manually save all intermediate certificates to 'chain.pem' files
# 3. Read OCSP endpoint URI from the certificate
# 4. Request a remote OCSP responder for certificate revocation status
##
openssl s_client -connect 'example.com:443' 2>&1 < '/dev/null' | sed -n '/-----BEGIN/,/-----END/p' > 'cert.pem'
openssl s_client -showcerts -host 'example.com' -port '443' < '/dev/null'
openssl x509 -in 'cert.pem' -noout -ocsp_uri
openssl ocsp -header "Host" "ocsp.stg-int-x1.letsencrypt.org" \
-issuer 'chain.pem' -VAfile 'chain.pem' -cert 'cert.pem' -text -url 'http://ocsp.stg-int-x1.letsencrypt.org'