30

My goal is to create a certificate with opensslsimilar to this one generated with cfssl

Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number:
            60:44:dc:0d:80:f4:54:55:e8:0d:95:61:f8:8f:b7:7e:f7:8d:29:69
    Signature Algorithm: ecdsa-with-SHA384
        Issuer: C=US, ST=California, L=San Francisco, O=Honest Achmed's Used Certificates, OU=Hastily-Generated Values Divison, CN=Autogenerated CA
        Validity
            Not Before: Jan 30 14:18:00 2017 GMT
            Not After : Jan 30 14:18:00 2018 GMT
        Subject: L=the internet, O=autogenerated, OU=etcd cluster, CN=etcd
        Subject Public Key Info:
            Public Key Algorithm: id-ecPublicKey
                Public-Key: (384 bit)
                pub: 
                    04:53:03:35:3e:cc:4f:19:19:46:0c:f2:81:a0:15:
                    c9:9e:e1:ab:7f:19:66:14:c8:7a:27:2b:68:ca:c9:
                    4d:cb:a9:c9:24:eb:cc:83:d8:9c:45:9d:aa:5c:3f:
                    f5:7b:7c:56:da:3e:4f:ec:5e:a6:68:15:23:51:97:
                    2c:c8:68:75:57:bb:26:e8:5e:d0:ca:c5:00:cb:f3:
                    b1:24:af:05:b6:c4:58:18:44:c4:a7:40:1a:35:d6:
                    d2:6a:9d:3d:bd:66:e5
                ASN1 OID: secp384r1
                NIST CURVE: P-384
        X509v3 extensions:
            X509v3 Key Usage: critical
                Digital Signature, Key Encipherment
            X509v3 Extended Key Usage: 
                TLS Web Server Authentication, TLS Web Client Authentication
            X509v3 Basic Constraints: critical
                CA:FALSE
            X509v3 Subject Key Identifier: 
                86:DF:8E:43:75:4A:75:B0:BF:D5:DC:17:75:A4:FC:8C:23:76:CF:75
            X509v3 Authority Key Identifier: 
                keyid:3B:65:F0:74:60:17:FC:0D:4E:CF:7A:63:5F:DB:6F:B3:CC:95:39:71

            X509v3 Subject Alternative Name: 
                DNS:localhost, IP Address:192.168.73.120, IP Address:192.168.73.121
    Signature Algorithm: ecdsa-with-SHA384
         30:64:02:30:01:6f:4a:4e:71:06:e8:79:b6:46:72:ae:13:21:
         fd:0b:91:ab:a9:18:a2:2a:ec:89:f3:c9:18:e3:31:7e:a7:d3:
         51:8d:b8:e2:8c:64:32:33:63:d7:54:7c:1d:67:08:e5:02:30:
         05:92:43:9d:51:a6:92:d6:42:82:2f:86:9c:0e:31:be:47:51:
         d8:6d:68:c6:83:a1:24:9b:25:e4:15:af:fc:65:96:28:8f:de:
         4d:b4:84:73:8a:cd:44:af:df:96:91:cd

In order to do so, I'm running the following commands:

openssl genrsa -out etcd1-key.pem 2048
openssl req -new -key etcd1-key.pem -config openssl.conf -subj '/CN=etcd' -out etcd1.csr
openssl x509 -req -in etcd1.csr -CA ca.pem -CAkey ca-key.pem -CAcreateserial -out etcd1.pem -days 1024 -sha256

The content of openssl.conf is:

[req]
req_extensions = v3_req
distinguished_name = dn

[dn]

[v3_req]
basicConstraints = CA:FALSE
keyUsage = digitalSignature, keyEncipherment
subjectAltName = IP:127.0.0.1, IP:192.168.73.120, IP:192.168.73.121

This is the csr file:

Certificate Request:
    Data:
        Version: 0 (0x0)
        Subject: CN=etcd
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                Public-Key: (2048 bit)
                Modulus:
                    00:a7:cd:eb:4c:9b:d0:30:f6:65:21:da:26:1c:e0:
                    82:cd:d4:79:d6:51:95:ec:9a:cb:0f:f9:99:14:cd:
                    dc:ba:ee:0d:5c:2e:ed:05:88:6b:c6:36:16:34:64:
                    5d:89:27:05:89:d2:38:99:24:47:a1:95:eb:7c:c8:
                    3f:d0:c1:cf:f2:41:0c:09:2d:03:e9:fc:ac:37:30:
                    f6:53:c7:e1:6e:12:bb:dc:8d:c5:4a:ba:77:ba:4b:
                    c5:b5:7f:0f:68:a3:e2:e8:c8:24:1a:f4:46:6f:41:
                    ba:03:02:42:6d:44:dd:95:47:b4:9f:c7:b6:de:c5:
                    91:b7:27:62:85:ba:17:2b:df:25:b6:0c:09:05:04:
                    a5:36:22:55:8a:9f:5b:fc:dd:53:d0:19:00:c8:90:
                    74:b8:18:66:f2:c9:44:2c:45:0f:01:3e:f4:fe:3b:
                    6e:09:d7:3f:ea:f3:e9:ab:b8:32:c2:f7:e2:af:2a:
                    d5:a7:79:2a:ec:75:8a:24:be:b5:a8:21:37:f0:b8:
                    cf:63:6f:0f:82:14:10:8c:21:c6:56:31:3a:e7:28:
                    18:76:4e:ac:19:fa:e7:02:e2:56:ab:03:a1:8e:2f:
                    5d:c9:e4:e7:b6:e4:12:d3:41:b4:b0:a0:94:b9:24:
                    d6:4d:14:20:43:d2:04:94:58:23:7f:76:d5:28:65:
                    b5:9f
                Exponent: 65537 (0x10001)
        Attributes:
        Requested Extensions:
            X509v3 Basic Constraints: 
                CA:FALSE
            X509v3 Key Usage: 
                Digital Signature, Key Encipherment
            X509v3 Subject Alternative Name: 
                IP Address:127.0.0.1, IP Address:192.168.73.120, IP Address:192.168.73.121
    Signature Algorithm: sha256WithRSAEncryption
         29:87:46:77:85:2e:22:a8:1d:5c:c4:f9:b4:f7:ae:e7:99:d9:
         a3:24:31:51:1f:57:f5:a4:40:1d:a6:16:4e:af:eb:60:f5:ac:
         10:92:9b:25:be:e6:79:e7:99:04:2d:80:a1:3d:42:62:77:16:
         40:52:38:27:3b:fe:b5:d6:41:59:68:0c:38:47:57:00:d6:2f:
         83:16:99:8a:70:5d:a8:0a:e8:b7:1b:c6:b9:69:70:6c:ee:84:
         04:8e:6a:3a:27:5e:ce:97:88:4c:88:93:69:11:17:59:95:e8:
         9a:da:b3:9b:37:d5:38:81:2e:b8:41:f8:32:7f:0b:50:d3:30:
         c5:51:c4:5c:aa:f8:ff:c6:08:44:e5:58:26:f7:ad:ba:e2:76:
         f1:c1:c5:08:e6:b5:29:cb:f5:ce:f8:0b:45:a2:1d:f0:ee:d2:
         1b:be:75:a6:4a:16:f0:9f:ec:b2:1a:49:31:a5:de:5e:ea:54:
         27:0c:47:a2:8b:6f:aa:05:d9:b8:3c:20:81:28:bd:b8:0a:76:
         39:f6:2b:4a:7f:e7:93:44:03:30:ce:b4:3e:b8:b2:55:9b:c4:
         06:65:61:16:26:02:d0:d3:01:cb:89:fc:6f:3f:7d:0c:e8:12:
         a6:31:04:4e:bc:56:3f:42:31:49:1d:d5:c5:e0:09:25:97:3f:
         67:3a:5c:d3

And finally, this is the content of the certificate (etcd1.pem) that is generated:

Certificate:
    Data:
        Version: 1 (0x0)
        Serial Number: 10309206242166002114 (0x8f11a874ec8b51c2)
    Signature Algorithm: sha256WithRSAEncryption
        Issuer: CN=etcdCA
        Validity
            Not Before: Feb  1 14:12:24 2017 GMT
            Not After : Nov 22 14:12:24 2019 GMT
        Subject: CN=etcd
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                Public-Key: (2048 bit)
                Modulus:
                    00:db:79:86:ad:b3:96:64:b3:52:49:56:bd:d6:4f:
                    5c:ef:8c:90:86:4f:2f:f9:9a:42:f4:38:55:79:c6:
                    70:bb:86:37:45:52:1c:f1:97:67:83:c4:12:04:c4:
                    84:44:e9:28:c9:b2:ef:d1:24:a2:e6:1e:7b:c7:4c:
                    6e:36:aa:fb:3b:43:c0:2b:28:1f:68:79:36:f0:47:
                    10:ec:91:c0:f9:82:80:32:c3:c5:8b:5f:f9:38:9e:
                    23:67:de:17:fc:a7:cc:03:26:41:fd:67:74:5d:e7:
                    7e:d0:31:fb:a2:ad:1c:86:6a:da:6f:11:11:59:63:
                    d9:31:a6:14:30:6e:0b:0a:bb:4b:0f:ae:21:3a:f2:
                    4c:34:b3:43:9c:60:ef:af:52:db:51:ec:bf:81:71:
                    8f:d2:6c:8d:46:7b:6c:8a:5b:8f:74:53:36:0b:cd:
                    7a:fb:9c:a4:22:c3:75:10:42:7a:ae:c3:91:cf:16:
                    ff:5b:a2:34:e9:4b:c0:fe:8d:4d:71:a4:25:65:59:
                    27:24:7a:52:ec:2f:f9:b6:12:5d:aa:77:df:b1:97:
                    49:d5:c1:12:8d:0f:3c:39:b2:d7:42:2e:de:e9:1f:
                    41:3c:a6:69:27:ff:ed:30:55:6a:ce:08:fc:28:98:
                    79:d0:dc:0c:4f:0b:b6:c8:5d:80:bb:47:6c:60:6f:
                    81:cd
                Exponent: 65537 (0x10001)
    Signature Algorithm: sha256WithRSAEncryption
         51:06:03:cb:21:3b:34:e1:2c:9e:16:cc:f1:64:9d:bb:13:11:
         24:fd:2e:67:22:83:9e:91:09:9b:4b:b8:f2:c1:03:5c:45:bf:
         79:0d:c3:04:81:a7:ce:b9:89:64:ab:ae:7f:86:24:79:cf:e4:
         ea:63:73:e3:a3:e0:ef:70:47:f6:19:84:f9:78:e4:27:75:f5:
         69:2e:ca:14:47:bd:73:9f:c9:0d:25:73:09:a1:cd:11:67:0a:
         eb:3b:b2:b0:b3:97:16:37:23:08:ea:a8:5a:fd:25:52:17:8b:
         1e:99:b0:d6:8d:fc:ba:dc:85:29:1c:2a:8c:ea:5a:65:81:fc:
         12:50:b1:25:a1:9f:56:8b:8a:d5:15:cc:17:bb:4c:60:4e:da:
         d3:a2:08:a8:7d:95:19:67:dc:6f:4b:4f:6f:49:f0:81:66:b9:
         65:45:75:dc:c7:35:28:ce:f4:55:c4:82:db:fa:b1:48:6d:05:
         b2:ac:65:ee:cd:b5:b2:52:b7:dc:3c:9c:67:a5:08:28:2e:57:
         57:65:46:16:54:6b:6d:be:73:d2:2f:bd:f5:12:b8:84:43:2a:
         f1:15:bd:1a:c1:37:76:20:9f:00:0d:a4:28:e4:c7:ad:0a:d9:
         1d:08:e3:d4:77:d7:e1:63:d8:02:57:ed:49:71:7f:c7:be:ae:
         39:06:5c:09

As you can see, it's missing the X509v3 extensions section, and I don't know why, because it's there in the csr.

So, what's missing in the last command to include the extensions??

2
  • 3
    Same problem here! Thanks for starting this discussion! Jan 2, 2020 at 14:42
  • 2
    Note that the known bug is about to be solved with -copy_extensions for openssl req and openssl x509. :) Jan 5, 2021 at 13:30

6 Answers 6

38

According to the bugs section of the x509 command documentation,

Extensions in certificates are not transferred to certificate requests and vice versa.

To work around this, I manually added the extensions to the self-signed certificate. This I did by copying the options from the [v3_req] section into a [v3_ca] section in a new file, and supplying that as an extensions file to the x509 command:

-extensions v3_ca -extfile ./ssl-extensions-x509.cnf
# ssl-extensions-x509.cnf

[v3_ca]
basicConstraints = CA:FALSE
keyUsage = digitalSignature, keyEncipherment
subjectAltName = IP:127.0.0.1, IP:192.168.73.120, IP:192.168.73.121
2
  • 1
    This even worked for me on windows with the Git-Bash. I think all other answers I read where missing the "-extensions v3_ca" parameter.
    – user200599
    Feb 26, 2019 at 12:45
  • 3
    The "bug" was fixed in v3.0.0 by the flag -copy_extensions, see github.com/openssl/openssl/pull/13711
    – gavenkoa
    May 4, 2022 at 9:15
5

For the openssl ca command the extensions are not copied from the CSR to the certificate unless they are included in the copy_extensions list within the active configuration (https://www.openssl.org/docs/man1.0.2/apps/ca.html).

Presumably the openssl x509 -req version has similar behaviors. There are concerns called out in the WARNINGS section of that manpage about using copy_extensions=copyall which mainly apply to having a real/conforming CA. If you're using it for private purposes you can stop, consider the risks, then enable it.

2
  • 4
    openssl x509 -req never copies extensions from the CSR; it doesn't have the copy_extensions option or even a default configfile as ca does. They only extensions it puts are from -extfile which the Q did not use. Mar 5, 2017 at 13:15
  • Also note copy_extensions by itself does NOT set the cert version to v3 as required; see unix.stackexchange.com/questions/371997/… Jun 25, 2017 at 7:33
3

2023 edition of the answer to this question is to use -copy_extensions=copyall as the bug in openssl is fixed in v3 as one of the commenter has mentioned.

Given the private key already exists, we can generate the certificate request with SAN extension:

openssl x509 -req -in request.csr -signkey private.key -out certificate.crt -days 3650 -extensions v3_req -extfile <(echo "[v3_req]\nsubjectAltName=DNS:hostname,IP:192.168.0.1")

And sign it while retaining all extensions:

openssl x509 -req -in request.csr -signkey private.key -out certificate.crt -days 3650 -copy_extensions=copyall

The certificate will contain all extensions of the request:

# openssl x509 -in certificate.crt -text -noout
Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number:
            3a:a8:f8:b7:24:ea:dd:dd:90:33:b9:0a:99:52:07:6c:8f:c1:90:c6
        Signature Algorithm: sha256WithRSAEncryption
        Issuer: CN = hostname
        Validity
            Not Before: Mar 28 13:57:19 2023 GMT
            Not After : Mar 25 13:57:19 2033 GMT
        Subject: CN = hostname
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                Public-Key: (2048 bit)
                Modulus:
                    00:a1:63:07:b0:07:dc:9d:56:72:7c:bf:1f:29:29:
                    4d:55:34:f7:8a:ed:8d:07:47:be:09:75:b2:2e:21:
                    e2:cb:aa:c4:0f:f9:3d:16:04:6b:12:02:cd:38:a9:
                    36:c8:53:1e:8e:f8:73:7d:a2:31:0f:e5:6a:7c:90:
                    b2:50:11:39:02:02:96:f3:d4:d7:c1:df:ac:cf:9b:
                    6b:03:ef:e4:c9:55:0b:c3:30:8e:f8:d3:8e:28:87:
                    e0:bd:01:af:a7:e8:2b:bd:73:da:04:7c:fb:00:f0:
                    d4:af:1b:e7:5f:52:93:8a:ae:be:c9:dd:1a:2e:dd:
                    44:05:fb:6b:fc:ee:10:93:17:7f:fe:02:7d:c8:ac:
                    91:9b:75:0f:26:74:76:32:ef:85:ec:a8:bb:e3:03:
                    97:db:41:df:bc:9e:db:d6:d7:7c:15:5b:d2:87:99:
                    5f:f5:9e:ec:e1:5e:21:5f:50:2e:fc:f0:e7:62:a8:
                    8f:59:42:25:a2:13:bb:73:d1:37:e4:74:14:c5:d2:
                    4d:18:83:88:6d:b0:80:0b:49:1c:bd:d9:16:66:30:
                    96:cc:8c:2d:4b:3a:21:bf:c9:5d:9d:e9:4a:89:a5:
                    26:54:30:08:7e:10:f6:0a:70:c1:3f:81:e2:70:fe:
                    00:4b:b1:d3:84:74:ae:29:e2:ac:09:9e:ab:78:b6:
                    86:27
                Exponent: 65537 (0x10001)
        X509v3 extensions:
            X509v3 Subject Alternative Name:
                DNS:hostname, IP Address:192.168.0.1
            X509v3 Subject Key Identifier:
                C5:84:7E:28:C9:70:3E:08:80:5F:DF:0B:CC:A7:EE:18:DA:FA:9A:7B
    Signature Algorithm: sha256WithRSAEncryption
    Signature Value:
        86:2a:74:f8:ea:c6:a7:92:75:d4:ba:6d:7a:86:a9:d9:9f:56:
        e1:7e:a6:27:b8:7f:b6:2a:56:b4:99:3c:c4:56:d8:a1:f8:1e:
        d8:9a:59:3e:22:65:3f:58:ac:32:9f:db:aa:df:a1:2e:a6:71:
        f2:61:6f:99:f5:fc:c7:e1:8f:dc:31:fa:31:16:2e:20:84:48:
        06:e1:48:3c:4e:dc:bf:14:d9:e2:53:c2:a3:38:e5:a7:55:f7:
        ca:f1:5d:43:5f:99:18:e1:d9:a5:df:ad:e4:b7:6e:03:f8:3f:
        63:a6:3b:e6:a0:5c:80:9d:61:36:6c:83:3d:a9:51:8e:af:cd:
        89:93:84:ab:1c:e5:69:a9:35:b0:19:ef:c4:53:14:f4:8b:10:
        61:38:92:48:70:a2:bc:99:5a:b4:ae:6c:cb:7a:b6:c6:8e:50:
        b1:bd:6a:7f:5b:e2:a8:46:a5:8d:af:b1:7e:35:17:11:00:19:
        ac:0f:a8:8a:bc:b5:df:44:57:71:3b:4e:75:ee:8e:b9:cc:e4:
        ec:40:41:e7:09:72:03:35:ea:71:1c:06:6c:da:34:8f:a1:cc:
        21:3a:cf:b3:4b:bc:8e:3a:fa:67:ff:aa:65:e6:cf:44:d9:ef:
        04:29:6a:ce:98:f6:d7:1f:16:f4:0c:94:1d:c4:48:97:47:b0:
        12:8f:fb:f1

Tested with:

# openssl version
OpenSSL 3.0.2 15 Mar 2022 (Library: OpenSSL 3.0.2 15 Mar 2022)

After you import generated this way the self-signed certificate e.g. into Window's Certificate Manager, the certificate is accepted as valid and the connection to your web-site is regarded secure by modern browsers (tested with Chrome 111, Edge 111, Firefox 111). This is a working way to created accepted self-signed certificate for internal services in a private network, e.g. for domains *.local.

Related to https://unix.stackexchange.com/questions/371997/creating-a-local-ssl-certificate/372393#372393 and https://serverfault.com/questions/880804/can-not-get-rid-of-neterr-cert-common-name-invalid-error-in-chrome-with-self

2

For self signed certificates add this to the openssl req -new -x509 command:

-extensions v3_req

or change req_extensions to x509_extensions, or have both if you want to use the config for both the request and a self signed cert for testing.

See here for some info about it: https://www.ibm.com/support/knowledgecenter/en/SSB23S_1.1.0.13/gtps7/cfgcert.html

4
  • That's correct for req -new -x509 as a single command -- which is already covered by other Qs -- but not for this Q which is req -new followed by x509 -req -CA*|-signkey (or even ca) Dec 8, 2019 at 3:47
  • Not entirely sure I'm following... req_extensions will generate a proper request, which will be signed by a 3rd party (which might not respect the extensions, but that's outside the scope of any command) or self-sign it, which involves setting x509_extensions instead of req_extensions. Do you mean that when signing with a different CA none of those params are being honored?
    – estani
    Dec 10, 2019 at 10:17
  • (I don't know why I wasn't notified on this.) I meant that openssl req -new _without_-x509 as used in this Q puts req_extensions (NOT x509_extensions) in the CSR, but openssl x509 -req -CA* as used in this Q to create a cert from a CSR IGNORES the extensions in the CSR. Your method does work for a self-signed cert with req -new -x509but does NOT work for this Q which is NOT self-signed and thus CANNOT use req -new -x509. Nov 20, 2020 at 22:40
  • This is helpful for those encountering the same problem with the "openssl req -new -x509" command. Thank you.
    – rtev
    Jun 12, 2021 at 15:36
0

Here is an example configuration to generate the correct CSR.

[ req ]
req_extensions = v3_req
distinguished_name = req_distinguished_name
x509_extensions = usr_cert
x509_extensions = v3_ca
[usr_cert]
basicConstraints = CA:FALSE
nsCertType = client, server, email
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
extendedKeyUsage = serverAuth, clientAuth, emailProtection
nsComment=KeyTalk Client Cert
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid,issuer
[v3_ca]
[req_distinguished_name]
commonName=www.stackexchange.com
localityName=
[v3_req]
basicConstraints = CA:FALSE
subjectAltName = @alt_names
extendedKeyUsage = serverAuth, clientAuth, emailProtection
keyUsage=nonRepudiation, digitalSignature, keyEncipherment
[v3_ca]
basicConstraints = CA:FALSE
extendedKeyUsage = serverAuth, clientAuth, emailProtection
keyUsage=nonRepudiation, digitalSignature, keyEncipherment
subjectAltName = @alt_names
[alt_names]
DNS.1 = www.stackexchange.com
2
  • 2
    Hello and welcome to Stack Exchange. Please don't post "code-only" (or in this case, "config-only") answers, as they give no information beyond the immediate code. Explain why this configuration achieves the desired results and possibly add external links to further reading.
    – user163495
    Apr 19, 2019 at 9:46
  • 1
    Specifying actual values in the DN section requires prompt = no which you failed to include, plus the Q already had the CSR correct over 2 years ago so no 'correction' is needed. Apr 20, 2019 at 0:04
0

You can also make it automatically on a single line. The following command is going to parse the CSR file and grab the alternative names from it.

openssl x509 -req -in infile.csr -CA RootCA.crt -CAkey RootCA.key -CAcreateserial -out outfile.crt -days 3600 -sha256 -extensions v3_req -extfile <(echo -e "[ v3_req ]\nbasicConstraints = CA:FALSE\nkeyUsage = digitalSignature, keyEncipherment\nsubjectAltName = $(openssl req -in infile.csr -noout -text | grep -A1 'Subject Alternative Name:' | tail -1 | sed 's/^\s*//1 ; s/IP Address:/IP:/g')")

After that, you can check the generated cert, looking for the "Subject Alternative Name" section, by issuing the command:

openssl x509 -noout -text -in outfile.crt

And the output should contain something like this:

<-- snip -->
X509v3 extensions:
X509v3 Basic Constraints:
    CA:FALSE
X509v3 Key Usage:
    Digital Signature, Key Encipherment
X509v3 Subject Alternative Name:
    IP Address:172.16.48.3, IP Address:FE80:E2C:0:0:0:0:0:3, DNS:server, DNS:server.local
<-- snip -->

You must log in to answer this question.