Support Multiple Common Names in Certificate - shell

I am trying to generate a self signed certificate for secured grpc communication. Below is what I have tried and connection between services work flawlessly in localhost.
However, the moment I deploy one of the services to production(Google Cloud Run) connection stops working. How can I make the certificate to support connection whether in localhost or in production.
Below is the certificate generation script I have tried.
generator.sh
# Clean Up
rm *.crt
echo "Generating certificates ..."
openssl genrsa -passout pass:1111 -des3 -out ca.key 4096
openssl req -passin pass:1111 -new -x509 -days 365 -key ca.key -out ca.crt -subj "/C=CL/ST=RM/L=Santiago/O=Test/OU=Test/CN=ca"
openssl genrsa -passout pass:1111 -des3 -out server.key 4096
openssl req -passin pass:1111 -new -key server.key -out server.csr -subj "/C=CL/ST=RM/L=Santiago/O=Test/OU=Server/CN=localhost"
openssl x509 -req -passin pass:1111 -days 365 -in server.csr -CA ca.crt -CAkey ca.key -set_serial 01 -out server.crt
openssl rsa -passin pass:1111 -in server.key -out server.key
openssl genrsa -passout pass:1111 -des3 -out client.key 4096
openssl req -passin pass:1111 -new -key client.key -out client.csr -subj "/C=CL/ST=RM/L=Santiago/O=Test/OU=Client/CN=localhost"
openssl x509 -passin pass:1111 -req -days 365 -in client.csr -CA ca.crt -CAkey ca.key -set_serial 01 -out client.crt
openssl rsa -passin pass:1111 -in client.key -out client.key
How can I make connection between services work all the time whether in localhost or in production which in my own case is Google Cloud Run (*.run.app)?
Thank you.

Your title says "multiple Common Names in certificate" but your body effectively says (twice) "work both for localhost and other host(s)". Those are entirely different. The X.509 certificate structure is quite flexible and it is technically possible to create one with multiple CommonName attributes in Subject, but if used for SSL/TLS (including HTTPS) only one of them will actually be considered when determining certificate validity; see rfc2818 and rfc6125.
There are two ways to have a certificate usable for multiple server names, which can actually be multiple names for one server (common in virtual hosting) or different servers (your case):
use a wildcard name. If you make all your machines have names which vary only in the first DNS label, such as the pattern you posted *.run.app, you can use one CommonName containing that wildcard. If your 'localhost' is actually your own computer or VM, you can use /etc/hosts or a local DNS like dnsmasq or unbound to assign it a name matching this pattern such as myownmachine.run.app and that will work with this certificate.
use the Subject Alternative Name/SAN extension which can contain multiple values each of which is either a DNS name or wildcard or an IP address (you probably don't want the latter, but it's available). All certs from real (public) CAs have used SAN since about 2010. For SAN in OpenSSL, see to start
Add SAN with private CA
Requested Extensions in CSR not being reflected in CRT
Self signed SSL certificate: Subject Alternative Name (SAN) gets lost when signing
https://security.stackexchange.com/questions/204036/specify-subject-alt-names-in-openssl
https://security.stackexchange.com/questions/190905/subject-alternative-name-in-certificate-signing-request-
https://security.stackexchange.com/questions/150078/missing-x509-extensions-with-an-openssl-generated-certificate
https://security.stackexchange.com/questions/74345/provide-subjectaltname-to-openssl-directly-on-command-line

Related

How to set up redis to work with SSL on a mac

Could you please help me to set up redis working with SSL on the local computer? I did once and it worked,
after some time, when I try to connect i ve got this error:
redis-cli --tls --cacert /usr/local/share/ca-certificates/ca.crt
Could not connect to Redis at 127.0.0.1:6379: SSL_connect failed: certificate verify failed
I followed this article https://godfrey-tutu.medium.com/redis-6-deployment-with-tls-authentication-on-centos-7-8b6e34d11cd0
i did this set of commands:
sudo -s // need to be able to run all next commands
mkdir /tmp/certs && cd /tmp/certs
openssl genrsa -out ca.key 4096
openssl req -x509 -new -nodes -sha256 -key ca.key -days 365 -subj '/O=A/CN=127.0.0.1' -out ca.crt
openssl genrsa -out redis.key 2048
mkdir /etc/ssl/private
openssl req -new -sha256 -nodes -key redis.key -subj '/O=A/CN=127.0.0.1' | openssl x509 -req -sha256 -CA ca.crt -CAkey ca.key -CAserial /etc/ssl/private/ca.txt -CAcreateserial -days 365 -out redis.crt
mkdir /usr/local/share/ca-certificates
cp ca.crt /usr/local/share/ca-certificates/
cp ca.key /etc/ssl/private/
cp redis.key /etc/ssl/private/
cp redis.crt /etc/ssl/
chown andrey /usr/local/share/ca-certificates/ca.crt
chmod 644 /usr/local/share/ca-certificates/ca.crt
chown andrey /etc/ssl/private/ca.key
chmod 400 /etc/ssl/private/ca.key
chown andrey /etc/ssl/private/redis.key
chmod 400 /etc/ssl/private/redis.key
chown andrey /etc/ssl/redis.crt
chmod 644 /etc/ssl/redis.crt
and here my redis config file
port 0
tls-port 6379
# Configure a X.509 certificate and private key to use for authenticating the
# server to connected clients, masters or cluster peers. These files should be
# PEM formatted.
#
tls-cert-file /etc/ssl/redis.crt
tls-key-file /etc/ssl/private/redis.key
# Configure a DH parameters file to enable Diffie-Hellman (DH) key exchange:
#
# tls-dh-params-file redis.dh
# Configure a CA certificate(s) bundle or directory to authenticate TLS/SSL
# clients and peers. Redis requires an explicit configuration of at least one
# of these, and will not implicitly use the system wide configuration.
#
tls-ca-cert-file /usr/local/share/ca-certificates/ca.crt
# tls-ca-cert-dir /etc/ssl/certs
# By default, clients (including replica servers) on a TLS port are required
# to authenticate using valid client side certificates.
#
# If "no" is specified, client certificates are not required and not accepted.
# If "optional" is specified, client certificates are accepted and must be
# valid if provided, but are not required.
#
tls-auth-clients no
# tls-auth-clients optional
# By default, a Redis replica does not attempt to establish a TLS connection
# with its master.
#
# Use the following directive to enable TLS on replication links.
#
# tls-replication yes
# By default, the Redis Cluster bus uses a plain TCP connection. To enable
# TLS for the bus protocol, use the following directive:
#
# tls-cluster yes
# Explicitly specify TLS versions to support. Allowed values are case insensitive
# and include "TLSv1", "TLSv1.1", "TLSv1.2", "TLSv1.3" (OpenSSL >= 1.1.1) or
# any combination. To enable only TLSv1.2 and TLSv1.3, use:
#
tls-protocols "TLSv1.2 TLSv1.3"
# Configure allowed ciphers. See the ciphers(1ssl) manpage for more information
# about the syntax of this string.
#
# Note: this configuration applies only to <= TLSv1.2.
#
# tls-ciphers DEFAULT:!MEDIUM
# Configure allowed TLSv1.3 ciphersuites. See the ciphers(1ssl) manpage for more
# information about the syntax of this string, and specifically for TLSv1.3
# ciphersuites.
#
tls-ciphersuites TLS_CHACHA20_POLY1305_SHA256
# When choosing a cipher, use the server's preference instead of the client
# preference. By default, the server follows the client's preference.
#
tls-prefer-server-ciphers no
# By default, TLS session caching is enabled to allow faster and less expensive
# reconnections by clients that support it. Use the following directive to disable
# caching.
#
# tls-session-caching no
# Change the default number of TLS sessions cached. A zero value sets the cache
# to unlimited size. The default size is 20480.
#
# tls-session-cache-size 5000
# Change the default timeout of cached TLS sessions. The default timeout is 300
# seconds.
#
# tls-session-cache-timeout 60
So this worked fine some days
I try to recreate certificates again but it does not help
what I am doing wrong?
The problem was in certificate generation:
openssl req -x509 -new -nodes -sha256 -key ca.key -days 365 -subj '/O=A/CN=127.0.0.1' -out ca.crt openssl genrsa -out redis.key 2048
openssl req -new -sha256 -nodes -key redis.key -subj '/O=A/CN=127.0.0.1' | openssl x509 -req -sha256 -CA ca.crt -CAkey ca.key -CAserial /etc/ssl/private/ca.txt -CAcreateserial -days 365 -out redis.crt
CN should be different –

AWS Cert Mgr - How to create client & device certificates?

From AWS tech talk, I have learnt that,
I am able to create private server certificate using below option:
-------------------
The server certificates serve the rationale of encrypting and decrypting the content.
Whereas
client certificate as the name implies is clearly used to identify a client to a respective user
A device certificate creates an identity for each “thing” in an IoT ecosystem,
making sure each device authenticates as it connects, and protects communication between devices.
We have created root CA and subordinate CA using AWS Cert mgr through console.
How to create device & client certificate(private) using ACM GoLang sdk?
[UPDATE after question asked for ACM]
Use the aws acm-pca issue-certificate command to request a certificate:
CLIENT_ID="device-0001"
CLIENT_SERIAL=0001
# Create the CSR and Private Key
openssl req -new -newkey rsa:2048 -days 365 -keyout ${CLIENT_ID}.key -out ${CLIENT_ID}.csr
# Replace --certificate-authority-arn with your ARN returned when you create the certificate authority.
aws acm-pca issue-certificate \
--csr file://${CLIENT_ID}.csr \
--signing-algorithm "SHA256WITHRSA" \
--validity Value=375,Type="DAYS" \
--idempotency-token 12983 \
--certificate-authority-arn arn:aws:acm-pca:region:account:\
certificate-authority/12345678-1234-1234-1234-123456789012
This command outputs the ARN, save this value for the next command ($MY-CERT-ARN)
aws acm-pca get-certificate \
--certificate-authority-arn arn:aws:acm-pca:region:account:\
certificate-authority/12345678-1234-1234-1234-123456789012 \
--certificate-arn $MY-CERT-ARN \
--output text > ${CLIENT_ID}-cert.pem
[END UPDATE]
Example code to generate a client certificate. Change CLIENT_ID and CLIENT_SERIAL for each certificate that you generate. ca.pem and ca.key are your CA certificate and private key.
CLIENT_ID="device-0001"
CLIENT_SERIAL=0001
openssl genrsa -aes256 -passout pass:xxxx -out ${CLIENT_ID}.pass.key 4096
openssl rsa -passin pass:xxxx -in ${CLIENT_ID}.pass.key -out ${CLIENT_ID}.key
rm ${CLIENT_ID}.pass.key
# generate the CSR
openssl req -new -key ${CLIENT_ID}.key -out ${CLIENT_ID}.csr
# issue this certificate, signed by the CA (ca.pem ca.key)
openssl x509 -req -days 375 -in ${CLIENT_ID}.csr -CA ca.pem -CAkey ca.key -set_serial ${CLIENT_SERIAL} -out ${CLIENT_ID}.pem
# Give the client the file: ${CLIENT_ID}.full.pem
cat ${CLIENT_ID}.key ${CLIENT_ID}.pem ca.pem > ${CLIENT_ID}.full.pem

How do I convert a SSH2 PUBLIC KEY (rsa-key file) to PEM? (Base-64 encoded public key of X.509 certificate)

I have a private/public key that was generated by Putty in the following format:
SSH2 PUBLIC KEY rsa-key
However, I am trying to get it to work with Docebo API using the JWT Grant Type, which requires a different format (according to this post).
How would I convert my key(s) to work with that format? Is there a way within Putty?
I figured out the steps to take to get the proper format of key using OpenSSL:
openssl genrsa -out private.key 1024
openssl req -new -x509 -key private.key -out publickey.cer
openssl x509 -in publickey.cer -out publickey.pem

How do I convert a pem to pfx file?

This has me confused:
Convert pfx to PEM:
openssl pkcs12 -in certificatename.pfx -out certificatename.pem
Do this dumps out a single plain text file.
Now how do I convert this plain text pem back to pfx?
The only commands I see to convert to pfx require the cer and private keys in separate files:
Convert CER and Private Key to PFX:
openssl pkcs12 -export -in certificatename.cer -inkey privateKey.key -out certificatename.pfx -certfile cacert.cer
Although I concur this is not really programming and arguably offtopic, numerous similar Qs about commandline tools (openssl, keytool, certutil etc) for (crypto) keys and certs are apparently accepted by the community (upvoted) -- but none I've seen directly addresses this point.
The different options on openssl pkcs12 -export allow you to provide the pieces in different files, but that is not required. If you do have the privatekey and chain of certs in one PEM file, as output by default by pkcs12 [not -export], you can let everything be read from that one file:
openssl pkcs12 -export -in file -out p12
# or ONLY IF the privatekey is first in the file
openssl pkcs12 -export <file -out p12
and you can even combine the pieces 'on the fly' as long as you put privatekey first:
cat privkey.pem mycert.pem chain.pem | openssl pkcs12 -export -out p12
You can use the command below to convert PEM (.pem, .crt, .cer) to PFX:
openssl pkcs12 -export -out **<your_new_file_name>**.pfx -inkey **<private_key_of_your_existing_certificate>**.key -in **<your_existing_certificate_file>**.crt
This will be very generic for all above mentioned files.

Digitally sign email in Ruby with S/MIME

Is there a way in Ruby to digitally sign email messages with S/MIME? Our group uses PKI and our users are conditioned to expect digital signatures for important messages.
I know I can invoke the openssl command line tool:
openssl smime -sign -signer $CERT_FILE -passin pass:$CERT_PASS
-in $UNSIGNED_MAIL -out $SIGNED_MAIL -certfile $CERT_CA_FILE
-from 'your ' -to 'recipients <email#address>'
-subject 'The Subject'
but I am hoping to utilize a Ruby solution.
I ended up using the above solution, but for those in a similar situation, you have to convert the PKI key (in .p12 file format) first: openssl pkcs12 -in #{#cert_file} -passin pass:#{#pass_phrase} -passout pass:#{#pass_phrase} -out #{out_file}

Resources