Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

OpenSSL Certificate (Version 3) with Subject Alternative Name

I'm using the OpenSSL command line tool to generate a self signed certificate. It seems to be working correctly except for two issues. I can't get it to create a .cer with a Subject Alternative Name (critical) and I haven't been able to figure out how to create a cert that is Version 3 (not sure if this is critical yet but would prefer learning how to set the version).

Has anyone done this successfully? The default config (.cfg) file has seemingly clear documentation (seen below):

This stuff is for subjectAltName and issuerAltname. Import the email address. subjectAltName=email:copy

However this does not work. My hunch is that the subject Alternative Name is not showing up b/c it is not present in the V1 specs, which is why I'm also pursuing setting he version.

Here is the config file I'm using:

[ req ]
default_bits        = 2048 
default_keyfile     = privkey.pem 
distinguished_name  = req_distinguished_name
emailAddress        = [email protected]
req_extensions          = v3_req
x509_extensions         = v3_ca

[req_distinguished_name]
C = [Press Enter to Continue]
C_default = US 
C_min = 2 
C_max = 2 

O = [Press Enter to Continue]
O_default = default 

0.OU=[Press Enter to Continue]
0.OU_default = default 
1.OU=[Press Enter to Continue]
1.OU_default = PKI 
2.OU=[Press Enter to Continue] 
2.OU_default = ABCD
commonName = Public FQDN of server 
commonName_max = 64

[ v3_req ]
basicConstraints = CA:FALSE
keyUsage = digitalSignature, nonRepudiation, keyEncipherment

[ v3_ca ]
subjectKeyIdentifier   = hash
authorityKeyIdentifier = keyid:always,issuer:always
subjectAltName         = email:[email protected]
issuerAltName          = issuer:copy
like image 741
Kandres22 Avatar asked May 31 '11 22:05

Kandres22


People also ask

How do I change the subject alternative name in OpenSSL?

OpenSSL does not allow you to pass Subject Alternative Names (SANs) through the command line, so you have to add them to a configuration file first. To do this, you have to locate your default OpenSSL configuration file. Location of OpenSSL configuration file: On Ubuntu, this is located at /usr/lib/ssl/openssl.

What is subject alternative name in certificate?

The Subject Alternative Name (SAN) is an extension to the X. 509 specification that allows users to specify additional host names for a single SSL certificate. The use of the SAN extension is standard practice for SSL certificates, and it's on its way to replacing the use of the common name.

How do I create an OpenSSL certificate with subject alternative name?

Create a configuration file for the certificate with Subject Alternative Name To create a Certificate using the Subject Alternative Name field you need to create an OpenSSL configuration file that allows creating certificates with this attribute. Create a new folder or use a folder with writing permissions.

Can OpenSSL be used to generate the Certificate Signing Request?

After a bit of research I found that OpenSSL can be used to generate the certificate signing request with Subject Alternative Names defined, as well as the private key. synology-1512.cnf (create using the text editor of your choice)

Is it possible to provide a subjectAltName-extension to the OpenSSL REQ module?

Is it possible to provide a subjectAltName-Extension to the openssl req module directly on the command line? I know it's possible via a openssl.cnf file, but that's not really elegant for batch-cre... Stack Exchange Network

What version of OpenSSL do you use with Heartbleed?

This is all done on CentOS 6.5 btw, with a Heartbleed-patched version of openssl 1.0.1-e. The focus was getting a certificate signing request with SANs in it that I could then sign.


6 Answers

Here is the simple steps for you

While generating the CSR you should use -config and -extensions and while generating certificate you should use -extfile and -extensions

Here is the example:

openssl req -new -nodes -keyout test.key  -out test.csr -days 3650 -subj "/C=US/ST=SCA/L=SCA/O=Oracle/OU=Java/CN=test cert" -config /etc/pki/tls/openssl.cnf -extensions v3_req
openssl x509 -req -days 3650 -in test.csr -CA cacert.pem -CAkey rootCA.key -CAcreateserial -out test.pem -extfile /etc/pki/tls/openssl.cnf  -extensions v3_req

hope this helps

like image 88
Raghu K Nair Avatar answered Oct 24 '22 04:10

Raghu K Nair


Alright, none of the other answers on this page worked for me, and I tried every last one of them. What worked for me was a little trick:

when requesting the cert:

-config <(cat /etc/ssl/openssl.cnf <(printf "[SAN]\nsubjectAltName=DNS:$SERVER")) \
-reqexts SAN

and when signing the cert:

-extfile <(cat /etc/ssl/openssl.cnf <(printf "[SAN]\nsubjectAltName=DNS:$SERVER")) \
-extensions SAN

Notice that this is a bash trick, <(some comamnds) makes the stdout output of some commands show as a temp file to the outer commands in bash.

So there is no confusion, here is a working script that covers everything from the start, including creating a certificate authority:

# if the server name is undefined, lets default to 'Some-Server'
SERVER="${SERVER:-Some-Server}"

CORPORATION=My-Corp
GROUP=My-Corporate-Group
CITY=City
STATE=State
COUNTRY=US

CERT_AUTH_PASS=`openssl rand -base64 32`
echo $CERT_AUTH_PASS > cert_auth_password
CERT_AUTH_PASS=`cat cert_auth_password`

# create the certificate authority
openssl \
  req \
  -subj "/CN=$SERVER.ca/OU=$GROUP/O=$CORPORATION/L=$CITY/ST=$STATE/C=$COUNTRY" \
  -new \
  -x509 \
  -passout pass:$CERT_AUTH_PASS \
  -keyout ca-cert.key \
  -out ca-cert.crt \
  -days 36500

# create client private key (used to decrypt the cert we get from the CA)
openssl genrsa -out $SERVER.key

# create the CSR(Certitificate Signing Request)
openssl \
  req \
  -new \
  -nodes \
  -subj "/CN=$SERVER/OU=$GROUP/O=$CORPORATION/L=$CITY/ST=$STATE/C=$COUNTRY" \
  -sha256 \
  -extensions v3_req \
  -reqexts SAN \
  -key $SERVER.key \
  -out $SERVER.csr \
  -config <(cat /etc/ssl/openssl.cnf <(printf "[SAN]\nsubjectAltName=DNS:$SERVER")) \
  -days 36500

# sign the certificate with the certificate authority
openssl \
  x509 \
  -req \
  -days 36500 \
  -in $SERVER.csr \
  -CA ca-cert.crt \
  -CAkey ca-cert.key \
  -CAcreateserial \
  -out $SERVER.crt \
  -extfile <(cat /etc/ssl/openssl.cnf <(printf "[SAN]\nsubjectAltName=DNS:$SERVER")) \
  -extensions SAN \
  -passin pass:$CERT_AUTH_PASS

We can then verify that the Subject Alternative name is in the final cert:

openssl x509 -in Some-Server.crt -text -noout

The pertinent section is:

    X509v3 extensions:
        X509v3 Subject Alternative Name: 
            DNS:Some-Server

So it worked! This is a cert that will be accepted by every major browser (including chrome), so long as you install the certificate authority in the browser. Thats ca-cert.crt that you will need to install.

Here is a sample configuration for nginx that would allow you to use the cert:

server {
    listen 443 ssl;
    listen [::]:443 ssl;
    server_name  localhost:443;

    ssl_certificate /etc/ssl/certs/Some-Server.crt;
    ssl_certificate_key /etc/ssl/private/Some-Server.key;
    ssl_dhparam /etc/ssl/certs/https-dhparam.pem;

    location / {
        root   /usr/share/nginx/html;
        index  index.html index.htm;
    }
}
like image 21
Jack Davidson Avatar answered Oct 24 '22 03:10

Jack Davidson


I got it to work with the following version (emailAddress was incorrectly placed) :

[ req ]
default_bits        = 2048 
default_keyfile     = privkey.pem 
distinguished_name  = req_distinguished_name
req_extensions          = v3_req
x509_extensions         = v3_ca

[req_distinguished_name]
C = [Press Enter to Continue]
C_default = US 
C_min = 2 
C_max = 2 

O = [Press Enter to Continue]
O_default = default 

0.OU=[Press Enter to Continue]
0.OU_default = default 
1.OU=[Press Enter to Continue]
1.OU_default = PKI 
2.OU=[Press Enter to Continue] 
2.OU_default = ABCD
commonName = Public FQDN of server 
commonName_max = 64
emailAddress = [Press Enter to Continue] 
emailAddress_default = [email protected]

[ v3_req ]
basicConstraints = CA:FALSE
keyUsage = digitalSignature, nonRepudiation, keyEncipherment

[ v3_ca ]
subjectKeyIdentifier   = hash
authorityKeyIdentifier = keyid:always,issuer:always
subjectAltName         = email:[email protected]
issuerAltName          = issuer:copy

Notes:

  • To generate the certificate I used:

    openssl req -config req.cnf -new -nodes -out req.pem -x509
    
  • I haven't seen much use for issuerAltname (if you have I'd be interested to know where).
  • Using issuer:always isn't recommended for authorityKeyIdentifier.
  • Using email:copy now works with subjectAltName.
  • v3_req section is superfluous (as well as req_extensions line.
like image 20
Mathias Brossard Avatar answered Oct 24 '22 05:10

Mathias Brossard


I just developed a web based tool that will generate this command automatically based on form input and display the output.


UPDATE: see certificatetools.com

It became so popular that I improved it and published it under its own domain name.

It will not only give you the downloadable .csr, but also provide the openssl commands that were used to generate it, and the needed openssl.cnf configuration options.

Example:

OpenSSL Commands

#generate the RSA private key
openssl genpkey -outform PEM -algorithm RSA -pkeyopt rsa_keygen_bits:2048 -out priv.key

#Create the CSR
openssl req -new -nodes -key priv.key -config csrconfig.txt -out cert.csr

OpenSSL CSR Config

[ req ]
default_md = sha256
prompt = no
req_extensions = req_ext
distinguished_name = req_distinguished_name
[ req_distinguished_name ]
commonName = example.com
countryName = US
stateOrProvinceName = Louisiana
localityName = Slidell
organizationName = Acme Inc.
[ req_ext ]
keyUsage=critical,digitalSignature,keyEncipherment
extendedKeyUsage=critical,serverAuth,clientAuth
subjectAltName = @alt_names
[ alt_names ]
IP.0 = 1.1.1.1
IP.1 = 2.2.2.2
DNS.0 = server1.example.com
DNS.1 = server2.example.com
email.0 = [email protected]
email.1 = [email protected]
like image 37
Lyas Spiehler Avatar answered Oct 24 '22 05:10

Lyas Spiehler


What command did you use to make the CSR certificate request? What command did you use to make the certificate file? Different answers for different circumstances you know.

Maybe you are not putting

subjectAltName=email:copy

in the section

[v3_req]

Maybe you are using openssl x509 to generate the certificate, if so you must use

-extfile /etc/pki/tls/openssl.cnf

because without that it doesnt use your config file

You also might need

-extensions v3_req

command line switch

like image 30
user1844882 Avatar answered Oct 24 '22 03:10

user1844882


I referred to several pages, and the most significant helps are from 1. https://geekflare.com/san-ssl-certificate/, 2. https://certificatetools.com/ (see answer from user40662), and 3. answer from Raghu K Nair about the command usage.

Then my successful try:

san.cnf

[ req ]
default_bits       = 2048
default_md         = sha256
distinguished_name = req_distinguished_name
req_extensions     = v3_req
[ req_distinguished_name ]
countryName            = CN                     # C=
stateOrProvinceName    = Shanghai               # ST=
localityName           = Shanghai               # L=
#postalCode             = 200000                 # L/postalcode=
#streetAddress          = "My Address"           # L/street=
organizationName       = My Corporation         # O=
organizationalUnitName = My Department          # OU=
commonName             = myname.mysoftware.mycorporation.com # CN=
emailAddress           = [email protected]     # CN/emailAddress=
[ v3_req ]
subjectAltName = @alt_names
[ alt_names ]
DNS.1   = myname.mysoftware.mycorporation.com
#DNS.2   = other2.com
#DNS.3   = other3.com

Command:

openssl req -x509 -nodes -days 365 -subj "/C=CN/ST=Shanghai/L=Shanghai/O=My Corporation/OU=My Department/CN=myname.mysoftware.mycorporation.com/[email protected]" -keyout privateKey.pem -out certificate.crt -config san.cnf -extensions v3_req
like image 31
robbie fan Avatar answered Oct 24 '22 04:10

robbie fan