133

I am trying to generate a self-signed certificate with OpenSSL with SubjectAltName in it.While I am generating the csr for the certificate, my guess is I have to use v3 extensions of OpenSSL x509. I am using :

openssl req -new -x509 -v3 -key private.key -out certificate.pem -days 730

Can someone help me with the exact syntax?

crthompson
  • 15,653
  • 6
  • 58
  • 80
mohanjot
  • 1,490
  • 2
  • 11
  • 15
  • 2
    Also see [How to create a self-signed certificate with openssl?](http://stackoverflow.com/a/27931596/608639) It provides the information to create a certificate with the Subject Alternate Name, and tells you other rules that apply so that the certificate will have the greatest chance of success with browsers and other user agents. – jww Jun 22 '15 at 16:04
  • answer at the bottom of this thread (https://stackoverflow.com/questions/27294589/creating-self-signed-certificate-for-domain-and-subdomains-neterr-cert-commo/59942460#59942460) using https://certificatetools.com/ will give you a good result and a usable cnf file – James Nelson Jan 28 '20 at 05:23

1 Answers1

182

Can someone help me with the exact syntax?

It's a three-step process, and it involves modifying the openssl.cnf file. You might be able to do it with only command line options, but I don't do it that way.

Find your openssl.cnf file. It is likely located in /usr/lib/ssl/openssl.cnf:

$ find /usr/lib -name openssl.cnf
/usr/lib/openssl.cnf
/usr/lib/openssh/openssl.cnf
/usr/lib/ssl/openssl.cnf

On my Debian system, /usr/lib/ssl/openssl.cnf is used by the built-in openssl program. On recent Debian systems it is located at /etc/ssl/openssl.cnf

You can determine which openssl.cnf is being used by adding a spurious XXX to the file and see if openssl chokes.


First, modify the req parameters. Add an alternate_names section to openssl.cnf with the names you want to use. There are no existing alternate_names sections, so it does not matter where you add it.

[ alternate_names ]

DNS.1        = example.com
DNS.2        = www.example.com
DNS.3        = mail.example.com
DNS.4        = ftp.example.com

Next, add the following to the existing [ v3_ca ] section. Search for the exact string [ v3_ca ]:

subjectAltName      = @alternate_names

You might change keyUsage to the following under [ v3_ca ]:

keyUsage = digitalSignature, keyEncipherment

digitalSignature and keyEncipherment are standard fare for a server certificate. Don't worry about nonRepudiation. It's a useless bit thought up by computer science guys/gals who wanted to be lawyers. It means nothing in the legal world.

In the end, the IETF (RFC 5280), browsers and CAs run fast and loose, so it probably does not matter what key usage you provide.


Second, modify the signing parameters. Find this line under the CA_default section:

# Extension copying option: use with caution.
# copy_extensions = copy

And change it to:

# Extension copying option: use with caution.
copy_extensions = copy

This ensures the SANs are copied into the certificate. The other ways to copy the DNS names are broken.


Third, generate your self-signed certificate:

$ openssl genrsa -out private.key 3072
$ openssl req -new -x509 -key private.key -sha256 -out certificate.pem -days 730
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
...

Finally, examine the certificate:

$ openssl x509 -in certificate.pem -text -noout
Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number: 9647297427330319047 (0x85e215e5869042c7)
    Signature Algorithm: sha256WithRSAEncryption
        Issuer: C=US, ST=MD, L=Baltimore, O=Test CA, Limited, CN=Test CA/emailAddress=test@example.com
        Validity
            Not Before: Feb  1 05:23:05 2014 GMT
            Not After : Feb  1 05:23:05 2016 GMT
        Subject: C=US, ST=MD, L=Baltimore, O=Test CA, Limited, CN=Test CA/emailAddress=test@example.com
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                Public-Key: (3072 bit)
                Modulus:
                    00:e2:e9:0e:9a:b8:52:d4:91:cf:ed:33:53:8e:35:
                    ...
                    d6:7d:ed:67:44:c3:65:38:5d:6c:94:e5:98:ab:8c:
                    72:1c:45:92:2c:88:a9:be:0b:f9
                Exponent: 65537 (0x10001)
        X509v3 extensions:
            X509v3 Subject Key Identifier:
                34:66:39:7C:EC:8B:70:80:9E:6F:95:89:DB:B5:B9:B8:D8:F8:AF:A4
            X509v3 Authority Key Identifier:
                keyid:34:66:39:7C:EC:8B:70:80:9E:6F:95:89:DB:B5:B9:B8:D8:F8:AF:A4

            X509v3 Basic Constraints: critical
                CA:FALSE
            X509v3 Key Usage:
                Digital Signature, Non Repudiation, Key Encipherment, Certificate Sign
            X509v3 Subject Alternative Name:
                DNS:example.com, DNS:www.example.com, DNS:mail.example.com, DNS:ftp.example.com
    Signature Algorithm: sha256WithRSAEncryption
         3b:28:fc:e3:b5:43:5a:d2:a0:b8:01:9b:fa:26:47:8e:5c:b7:
         ...
         71:21:b9:1f:fa:30:19:8b:be:d2:19:5a:84:6c:81:82:95:ef:
         8b:0a:bd:65:03:d1
Community
  • 1
  • 1
jww
  • 97,681
  • 90
  • 411
  • 885
  • Thanks noloader. I appreciate your reply. I did it the the same way. I was just thinking about a way of not updating openssl.cnf file for each IP Address (one of the fields I am updating in SubjectAlternateName) for every server. I had contacted a PEN Tester for his views too. As per him, keep updating the openssl.cnf file with a wrapper script which is fine but still becomes a hack. I was trying to find a way to pass subjectAltName as part of a command line command while using : openssl req -new -x509 ........... But I dont think that really exists. But I appreciate your help. – mohanjot Feb 04 '14 at 04:08
  • Yeah, its a hack because `openssl ca` and `openssl req` are kind of broken :( – jww Feb 04 '14 at 04:50
  • 1
    By the way, if you want to write your own program to do it, it will work. See the demos `mkreq.c` and `mkcert.c` in the `/crypto/demos` directory. – jww Feb 04 '14 at 05:20
  • 10
    I just copied that openssl file and adjusted it locally. Then generated everything with: `openssl genrsa -out cert.key 3072 -nodes` `openssl req -new -x509 -key cert.key -sha256 -config openssl.cnf -out cert.crt -days 730 -subj "/C=US/ST=private/L=province/O=city/CN=hostname.example.com"` – stwienert Mar 24 '14 at 16:35
  • 7
    There's also a nice trick to make this more flexible using environment variables described [here](http://www.crsr.net/Notes/SSL.html): `subjectAltName=$ENV::ALTNAME` (and set the env. var `ALTNAME=DNS:example.com,DNS:other.example.net`). – Bruno Nov 21 '14 at 20:39
  • @sebix `/usr/lib/ssl/openssl.cnf` is actually a symbolic link to `/etc/ssl/openssl.cnf`, so they are in fact the same file. – Bruno Nov 21 '14 at 20:41
  • 1
    Using openssl in Mac. When create CSR file, I can see the subjectAltName in the CSR file, but when create certificate from it, or directly with above command, I cannot see the subjectAltName in the certificate file. What can be the problem? Anyone knows? – karim Jun 10 '15 at 11:07
  • 7
    Note that you use `IP` instead of `DNS` for `alternate_names` if you're working with an ip address. You can also copy the config file locally and then specify it on the openssl command line with `-config my_config.cnf`. And you might have to uncomment `req_extensions = v3_req`. – Adversus Jun 07 '16 at 10:31
  • 6
    I never got this to work on OSX, but using the req.conf template at this link worked like a charm: https://support.citrix.com/article/CTX135602 (I'd extract the details into an answer but this question has been unhelpfully closed) – rymo May 08 '17 at 20:46
  • Also never got this to work on OSX. Used these instructions on an Ubuntu 16.04 machine using Vagrant, and mission accomplished. Thank you! – Iammesol May 11 '17 at 03:56
  • 4
    for some reason it doesn't like the subjectAltName = @alternate_names under v3_ca section. Could it be a typo? Here's the error I get: error:22097069:X509 V3 routines:DO_EXT_NCONF:invalid extension string:v3_conf.c:139:name=subjectAltName,section=@alternate_names 140487468840608:error:22098080:X509 V3 routines:X509V3_EXT_nconf:error in extension:v3_conf.c:93:name=subjectAltName, value=@alternate_names – James Nelson May 12 '17 at 20:42
  • @JamesNelson - `DO_EXT_NCONF` sounds new. I don't recall seeing in in 1.0.2 or below (but I could be wrong). Let's ping Matt Caswell. He cruises Stack Overflow on occasion and provides the expert insight since he's a OpenSSL team member. – jww May 12 '17 at 21:40
  • Thanks I finally got it working with a suggestion above, but I'm still curious. Works: "subjectAltName=$ENV::ALTNAME (and set the env. var ALTNAME=DNS:example.com,DNS:other.example.net" from @Bruno thanks both of you! – James Nelson May 13 '17 at 01:37
  • I could not recreate the error posted above by @JamesNelson (either in OpenSSL 1.1.0 or 1.0.2), I suspect a typo your config file – Matt Caswell May 15 '17 at 10:36
  • This post helped me create a self-signed certificate on Mac OSX: https://alexanderzeitler.com/articles/Fixing-Chrome-missing_subjectAltName-selfsigned-cert-openssl/ – carlosvini Jun 12 '17 at 16:29
  • 1
    Im working with WIN32OpenSSL (1.0.2), I did everything but I see at least when im checking the cert: X509v3 Basic Constraints: critical CA:FALSE, and SAN doesn't appears. Any help will be preciated – Leandro Bardelli Jul 13 '17 at 19:58
  • What should you answer in this case for the `Common Name (e.g. server FQDN or YOUR name)` question? Should it be `example.com` or `*.example.com`? – sdaau Sep 20 '17 at 11:33
  • @sdaau - Neither. Use "Example, LLC". – jww Sep 20 '17 at 11:41
  • 3
    There´s a solution, where you don´t have to modifiy the system-wide openssl.conf file in /usr/lib/openssl.conf, which I don´t really like for adhoc examples. All you have to use is the `-extfile` and `-extension` CLI parameters. Here´s an example: `openssl x509 -req -days 3650 -in alice.csr -signkey aliceprivate.key -out alice.crt -extfile alice-csr.conf -extensions v3_req`. This requires a `alice-csr.conf`, which has the `[v3_req]` part with the Subject Alternative Names configured. See fully running example here https://github.com/jonashackt/spring-boot-rest-clientcertificates-docker-compose – jonashackt Dec 12 '17 at 18:53
  • On Cygwin, I found `openssl.cnf` into `/usr/ssl`. – Maxime Pacary Jan 12 '18 at 17:54
  • I think we need to add subjectAltName in `[ req_ext ]` `subjectAltName = @alternate_names` instead of `[v3_ca]`. It worked for me – I'm_Pratik Nov 11 '20 at 10:26
  • 1
    @rymo That is the only thing that worked for me on Windows through Git BASH. The key that allowed it to be generated properly is the following openssl argument: `-extensions 'v3_req'` Without that it would not include the SANs, even with everything configured correctly. – jhyry-gcpud Aug 11 '21 at 22:47
  • I couldn't get the SAN values to copy to the certificate on Linux or macOS until I tried the single `openssl req -x509` command from the Citrix article linked by @rymo, as opposed to `openssl req` followed by `openssl x509`. As a bonus, this command avoids the need to manually create a CSR. – Blieque Dec 14 '21 at 13:08
  • This is much easier now. See [this answer](https://security.stackexchange.com/a/183973/184567) for adding the SubjectAltName to the certificate signing request. If we can re-open this question I'll provide a working example of creating a self signed cert in MacOS that browsers accept. – Lou Zell May 15 '23 at 16:44