create custom ssl certificate

In theory it is easy to create self-signed host certificates. But in practice there are some stumbling blocks when creating certificates. This example creates a root CA by using open-oource tool openssl. This are the basic steps:

  1. create certification authority certificate (root-ca)
  2. create private key and sign root ca
  3. create host private key
  4. create host certificate
  5. sign host certificate with CA

create certification authority (root ca)

We are starting with a text file named root-ca.cnf. It contains root ca configuration:

root-ca.cnf

[req] 
default_bits = 2048 
prompt = no 
default_md = sha256 
distinguished_name = dn 

[ dn ] 
C=DE 
ST=Nordrhein-Westfalen 
L=Dortmund 
O=unknown 
OU=Entwicklung 
emailAddress=mail@bytefusion.de
CN = www.bytefusion.de
  • line 2-4: set defaults
  • line 5/7: distinguished name
  • line 8+: country, state, city, …

As prerequisite in next step the private key is created:

create private key

$ openssl genrsa -out certs/root-ca-key.pem 2048

The req command creates a root ca certificate signed with the private key:

create certificate signed with private key

$ openssl req -x509 -new -key certs/root-ca-key.pem -sha256 -out certs/root-ca.pem -config root-ca.cnf

Openssl subcommand is used to verify contents of previously created x509 certificate:

show certificate contents

$ openssl x509 -in certs/root-ca.pem -text
Certificate:
    Data:
        Version: 1 (0x0)
        Serial Number:
            39:cf:cb:0f:af:2b:e8:56:0a:a0:e2:6e:3a:40:fc:e5:a0:b6:1e:56
        Signature Algorithm: sha256WithRSAEncryption
        Issuer: C = DE, ST = Nordrhein-Westfalen, L = Dortmund, O = unknown, OU = Entwicklung, emailAddress = mail@bytefusion.de, CN = www.bytefusion.de
        Validity
            Not Before: Jun 21 17:23:03 2019 GMT
            Not After : Jul 21 17:23:03 2019 GMT
        Subject: C = DE, ST = Nordrhein-Westfalen, L = Dortmund, O = unknown, OU = Entwicklung, emailAddress = mail@bytefusion.de, CN = www.bytefusion.de
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                RSA Public-Key: (2048 bit)
                Modulus:
                    00:a6:f4:db:c8:b3:90:b3:8a:cb:63:c5:79:07:27:
                    11:6a:0b:a0:e4:5c:a5:31:1c:e3:81:1e:9e:78:26:
                    12:63:db:2f:62:1a:84:0d:e6:0b:38:e8:db:c4:b2:
                    22:eb:6a:47:9f:37:af:3e:b7:ff:90:a7:19:03:d3:
                    8c:52:af:ee:fd:c8:0e:14:4d:6c:26:8c:84:cd:f3:
                    95:c1:b3:ae:67:c8:77:cb:98:f1:fd:13:44:ab:09:
                    dc:b5:01:7b:34:10:3d:d4:2f:51:41:0f:6b:be:4a:
                    03:90:eb:dc:ae:fc:ec:0d:ed:b3:e1:c7:8d:55:87:
                    da:b2:50:f5:55:36:83:87:a9:f3:4e:0f:d5:e3:d5:
                    ff:03:ea:76:be:77:31:26:23:a0:09:a7:10:37:81:
                    9b:82:e5:4b:fe:90:55:4d:1f:b3:cb:9d:18:c2:b2:
                    b3:29:d7:18:de:0e:22:74:46:b9:46:d6:73:a0:a3:
                    db:6d:a8:f7:c4:6d:9e:15:c6:14:c5:9b:77:67:93:
                    7a:8a:22:72:2c:5a:87:8c:d4:f6:70:c8:bc:4f:70:
                    8b:63:fb:60:f5:52:df:f8:aa:da:df:3e:08:11:2e:
                    1c:b0:ce:39:bd:75:30:e8:5e:7f:a7:71:32:27:3b:
                    5a:20:17:be:de:69:31:55:92:46:80:02:66:17:fa:
                    b2:31
                Exponent: 65537 (0x10001)
    Signature Algorithm: sha256WithRSAEncryption
         a3:ba:d5:de:d8:cb:36:aa:99:2e:56:69:0d:58:f4:e3:32:ae:
         d0:76:60:e9:93:66:08:b2:40:dd:cd:90:64:4e:0b:2e:15:c6:
         c7:3b:69:89:25:56:43:d3:bf:f4:ad:70:f0:7b:d2:4e:87:44:
         a4:08:97:73:8b:23:70:60:b3:ab:ee:04:66:de:ed:37:c4:d2:
         1c:0f:50:ed:af:61:48:16:c4:c0:56:53:20:85:03:d4:08:e6:
         06:11:99:84:5d:54:65:3b:2f:92:d2:a1:08:b1:38:f7:c4:d9:
         75:1c:6b:6b:51:93:5a:fc:3d:ec:c0:bf:d5:a7:30:5b:54:49:
         79:0d:ea:81:6b:e9:b0:4c:c9:db:94:82:c9:49:d7:12:18:cc:
         43:94:8c:ea:46:73:b2:01:e3:08:a0:27:1a:10:db:6c:82:66:
         9b:e5:d3:47:ca:1d:7d:b2:1c:b7:45:2f:2d:39:38:25:4e:4b:
         6e:da:19:df:55:48:46:93:0a:de:3c:60:05:16:7e:ba:ab:a2:
         15:ec:72:ec:bd:0b:a1:e5:a4:e9:2e:c0:ef:55:89:a9:a0:b0:
         11:70:85:36:2a:96:68:10:c4:88:c5:b6:e1:d2:23:14:17:0e:
         84:34:e1:9d:42:64:07:99:9e:35:0d:2a:83:e0:a5:1f:a3:bc:
         65:5a:da:64
-----BEGIN CERTIFICATE-----
MIID0zCCArsCFDnPyw+vK+hWCqDibjpA/OWgth5WMA0GCSqGSIb3DQEBCwUAMIGl
MQswCQYDVQQGEwJERTEcMBoGA1UECAwTTm9yZHJoZWluLVdlc3RmYWxlbjERMA8G
A1UEBwwIRG9ydG11bmQxEDAOBgNVBAoMB3Vua25vd24xFDASBgNVBAsMC0VudHdp
Y2tsdW5nMSEwHwYJKoZIhvcNAQkBFhJtYWlsQGJ5dGVmdXNpb24uZGUxGjAYBgNV
BAMMEXd3dy5ieXRlZnVzaW9uLmRlMB4XDTE5MDYyMTE3MjMwM1oXDTE5MDcyMTE3
MjMwM1owgaUxCzAJBgNVBAYTAkRFMRwwGgYDVQQIDBNOb3JkcmhlaW4tV2VzdGZh
bGVuMREwDwYDVQQHDAhEb3J0bXVuZDEQMA4GA1UECgwHdW5rbm93bjEUMBIGA1UE
CwwLRW50d2lja2x1bmcxITAfBgkqhkiG9w0BCQEWEm1haWxAYnl0ZWZ1c2lvbi5k
ZTEaMBgGA1UEAwwRd3d3LmJ5dGVmdXNpb24uZGUwggEiMA0GCSqGSIb3DQEBAQUA
A4IBDwAwggEKAoIBAQCm9NvIs5CzistjxXkHJxFqC6DkXKUxHOOBHp54JhJj2y9i
GoQN5gs46NvEsiLrakefN68+t/+QpxkD04xSr+79yA4UTWwmjITN85XBs65nyHfL
mPH9E0SrCdy1AXs0ED3UL1FBD2u+SgOQ69yu/OwN7bPhx41Vh9qyUPVVNoOHqfNO
D9Xj1f8D6na+dzEmI6AJpxA3gZuC5Uv+kFVNH7PLnRjCsrMp1xjeDiJ0RrlG1nOg
o9ttqPfEbZ4VxhTFm3dnk3qKInIsWoeM1PZwyLxPcItj+2D1Ut/4qtrfPggRLhyw
zjm9dTDoXn+ncTInO1ogF77eaTFVkkaAAmYX+rIxAgMBAAEwDQYJKoZIhvcNAQEL
BQADggEBAKO61d7YyzaqmS5WaQ1Y9OMyrtB2YOmTZgiyQN3NkGROCy4Vxsc7aYkl
VkPTv/StcPB70k6HRKQIl3OLI3Bgs6vuBGbe7TfE0hwPUO2vYUgWxMBWUyCFA9QI
5gYRmYRdVGU7L5LSoQixOPfE2XUca2tRk1r8PezAv9WnMFtUSXkN6oFr6bBMyduU
gslJ1xIYzEOUjOpGc7IB4wigJxoQ22yCZpvl00fKHX2yHLdFLy05OCVOS27aGd9V
SEaTCt48YAUWfrqrohXscuy9C6HlpOkuwO9ViamgsBFwhTYqlmgQxIjFtuHSIxQX
DoQ04Z1CZAeZnjUNKoPgpR+jvGVa2mQ=
-----END CERTIFICATE-----

create host private ssl key

Create a private key for host. We used the genrsa sub command to create a private key. Repeat these steps in similar way to create a host key:

create private key

$ openssl genrsa -out certs/bytefusion-pkcs12-key.pem 2048

Java runtime requires pkcs8 format for proper working, so format is transformed into pkcs8 format:

convert pkcs12 to pkcs8 format

$ openssl pkcs8 -v1 "PBE-SHA1-3DES" -in "certs/bytefusion-pkcs12-key.pem" -topk8 -out "certs/bytefusion-key.pem" -nocrypt

create host ssl certificate

Creating host certificate with extended attributes is tricky because of an bug in openssl.

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

It is possible to produce invalid certificates or requests by specifying the wrong private key or using inconsistent options in some cases: these should be checked.

There should be options to explicitly set such things as start and end dates rather than an offset from the current time.”

https://www.openssl.org/docs/man1.1.0/man1/x509.html#BUGS

Direct transfer from root ca is not possible. So apply extended attributes when creating host certificate. Use configuration file with missing attributes:le:

bytefusion.cnf

[req] 
default_bits = 2048 
prompt = no 
default_md = sha256 
distinguished_name = dn 
req_extensions = extensions
x509_extensions = extensions

[ dn ] 
C=DE 
ST=Nordrhein-Westfalen 
L=Dortmund 
O=unknown 
OU=Entwicklung 
emailAddress=mail@bytefusion.de
CN = *

[ extensions ]
subjectAltName = @alt_names

[ alt_names ]
DNS.1 = elasticsearch
DNS.2 = elasticsearch_1
DNS.3 = elastichq
DNS.4 = elasticsearch
DNS.5 = kirk

Apply this configuration to certificate sign request (csr).

create certificate sign request

$ openssl req -new -key certs/bytefusion-key.pem -out certs/bytefusion.csr -config bytefusion.cnf

sign host certificate with certification authority (ca)

And finally create server certificates signed by our previously creates ca:

sign host certificate with root ca

$ openssl x509 -req -in certs/bytefusion.csr -CA certs/root-ca.pem -CAkey certs/root-ca-key.pem -CAcreateserial -out certs/bytefusion.pem -sha256 -extensions extensions -extfile bytefusion.cnf

Use following command to show certificate contents:

show contents

$ openssl x509 -in certs/bytefusion.pem -text
Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number:
            0c:1b:de:30:17:4e:42:31:50:cd:13:7e:c4:de:47:fa:65:79:32:01
        Signature Algorithm: sha256WithRSAEncryption
        Issuer: C = DE, ST = Nordrhein-Westfalen, L = Dortmund, O = unknown, OU = Entwicklung, emailAddress = mail@bytefusion.de, CN = www.bytefusion.de
        Validity
            Not Before: Jun 21 17:31:32 2019 GMT
            Not After : Jul 21 17:31:32 2019 GMT
        Subject: C = DE, ST = Nordrhein-Westfalen, L = Dortmund, O = unknown, OU = Entwicklung, emailAddress = mail@bytefusion.de, CN = *
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                RSA Public-Key: (2048 bit)
                Modulus:
                    00:98:3a:3f:a9:8e:25:d5:0d:d8:72:06:8e:90:68:
                    0f:ec:66:69:ca:55:6e:3a:e7:94:64:32:1e:ea:b2:
                    3a:77:a8:4c:8d:40:7c:f2:77:df:41:18:90:62:ac:
                    a8:95:fb:aa:b2:07:d5:04:9f:8a:df:77:48:5b:1a:
                    07:13:da:f9:a1:1d:2e:e1:5d:40:5e:55:91:da:1c:
                    80:5f:e9:1e:93:12:42:b1:6c:89:33:2f:35:cc:be:
                    91:73:68:c8:18:20:f4:b8:5d:5e:5e:51:d1:3c:0d:
                    cf:59:1f:7f:d7:bc:15:5a:1f:fc:a0:63:43:d7:5d:
                    6d:5b:64:e6:88:7a:f9:ed:84:ef:01:5a:11:60:e4:
                    d6:4f:68:28:77:6d:68:0b:52:fc:b6:dc:a7:7d:df:
                    fd:95:30:b6:7e:16:b6:3b:3a:52:4f:99:99:36:78:
                    ac:9f:24:96:88:d6:b6:0b:17:f6:fe:33:c7:49:30:
                    78:b3:96:9c:31:53:2d:fb:34:e5:34:ef:89:07:25:
                    bd:58:1b:f1:9c:8d:89:cf:31:79:44:d8:ad:22:1f:
                    06:08:b3:1e:e7:b5:81:88:52:84:2b:bc:88:a9:1e:
                    b4:bf:b6:bb:b3:c3:18:42:dc:d7:5f:4c:f1:ac:5d:
                    43:d8:72:e6:60:f7:9b:9a:d5:91:14:88:58:74:93:
                    4f:6d
                Exponent: 65537 (0x10001)
        X509v3 extensions:
            X509v3 Subject Alternative Name:
                DNS:elasticsearch, DNS:elasticsearch_1, DNS:elastichq, DNS:elasticsearch, DNS:kirk
    Signature Algorithm: sha256WithRSAEncryption
         ce:c2:a1:14:fc:49:ba:4e:66:13:fe:d7:c6:f6:4c:a6:1a:79:
         cf:79:cf:f7:ce:05:65:e2:ba:c8:da:2b:c1:eb:01:42:d7:52:
         5b:42:42:5b:92:de:e9:03:94:3f:16:47:6c:79:3e:08:0b:1f:
         63:16:38:a2:e2:7a:73:af:67:e1:41:b9:c2:bd:fc:fe:78:39:
         c8:41:c8:05:64:6a:99:9a:1f:b0:5c:47:18:5c:73:c5:a1:04:
         e9:cb:d7:cd:22:aa:96:33:04:3e:a3:e1:c8:fb:46:fb:73:1f:
         d9:65:a2:ff:73:56:35:78:80:7c:13:ca:05:60:48:96:df:19:
         ca:ff:f0:65:52:ee:da:e4:dc:4b:c8:3f:06:69:a5:cd:75:e9:
         67:86:53:05:0f:e2:c9:a3:ae:d2:61:cb:ed:f3:6e:d2:4d:c5:
         12:ab:21:46:fd:ef:87:1d:69:12:ba:92:d6:66:18:de:b2:57:
         32:93:1a:9e:0a:15:5e:6f:4b:61:35:18:23:10:90:b9:78:83:
         40:41:ef:43:55:19:eb:f2:7d:80:30:35:de:da:49:88:65:08:
         fc:7c:20:fd:06:f0:2d:6d:67:88:a6:a4:72:2e:12:69:e2:98:
         66:6a:5a:56:49:e0:3e:f6:c0:3c:e0:35:08:49:fa:69:c1:5f:
         bf:67:92:43
-----BEGIN CERTIFICATE-----
MIIEFzCCAv+gAwIBAgIUDBveMBdOQjFQzRN+xN5H+mV5MgEwDQYJKoZIhvcNAQEL
BQAwgaUxCzAJBgNVBAYTAkRFMRwwGgYDVQQIDBNOb3JkcmhlaW4tV2VzdGZhbGVu
MREwDwYDVQQHDAhEb3J0bXVuZDEQMA4GA1UECgwHdW5rbm93bjEUMBIGA1UECwwL
RW50d2lja2x1bmcxITAfBgkqhkiG9w0BCQEWEm1haWxAYnl0ZWZ1c2lvbi5kZTEa
MBgGA1UEAwwRd3d3LmJ5dGVmdXNpb24uZGUwHhcNMTkwNjIxMTczMTMyWhcNMTkw
NzIxMTczMTMyWjCBlTELMAkGA1UEBhMCREUxHDAaBgNVBAgME05vcmRyaGVpbi1X
ZXN0ZmFsZW4xETAPBgNVBAcMCERvcnRtdW5kMRAwDgYDVQQKDAd1bmtub3duMRQw
EgYDVQQLDAtFbnR3aWNrbHVuZzEhMB8GCSqGSIb3DQEJARYSbWFpbEBieXRlZnVz
aW9uLmRlMQowCAYDVQQDDAEqMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC
AQEAmDo/qY4l1Q3YcgaOkGgP7GZpylVuOueUZDIe6rI6d6hMjUB88nffQRiQYqyo
lfuqsgfVBJ+K33dIWxoHE9r5oR0u4V1AXlWR2hyAX+kekxJCsWyJMy81zL6Rc2jI
GCD0uF1eXlHRPA3PWR9/17wVWh/8oGND111tW2TmiHr57YTvAVoRYOTWT2god21o
C1L8ttynfd/9lTC2fha2OzpST5mZNnisnySWiNa2Cxf2/jPHSTB4s5acMVMt+zTl
NO+JByW9WBvxnI2JzzF5RNitIh8GCLMe57WBiFKEK7yIqR60v7a7s8MYQtzXX0zx
rF1D2HLmYPebmtWRFIhYdJNPbQIDAQABo00wSzBJBgNVHREEQjBAgg1lbGFzdGlj
c2VhcmNogg9lbGFzdGljc2VhcmNoXzGCCWVsYXN0aWNocYINZWxhc3RpY3NlYXJj
aIIEa2lyazANBgkqhkiG9w0BAQsFAAOCAQEAzsKhFPxJuk5mE/7XxvZMphp5z3nP
984FZeK6yNorwesBQtdSW0JCW5Le6QOUPxZHbHk+CAsfYxY4ouJ6c69n4UG5wr38
/ng5yEHIBWRqmZofsFxHGFxzxaEE6cvXzSKqljMEPqPhyPtG+3Mf2WWi/3NWNXiA
fBPKBWBIlt8Zyv/wZVLu2uTcS8g/BmmlzXXpZ4ZTBQ/iyaOu0mHL7fNu0k3FEqsh
Rv3vhx1pErqS1mYY3rJXMpMangoVXm9LYTUYIxCQuXiDQEHvQ1UZ6/J9gDA13tpJ
iGUI/Hwg/QbwLW1niKakci4SaeKYZmpaVkngPvbAPOA1CEn6acFfv2eSQw==
-----END CERTIFICATE-----

conclusion

Openssl offers several ways to create self signed certificates. Use the way described in this article to create your own certificates. Adapt configuration file to your needs. Using configuration file helps to shorten command line.

full example

#!/bin/bash 

mkdir certs

# create private key
openssl genrsa -out certs/root-ca-key.pem 2048

# create root ca
openssl req -x509 -new -key certs/root-ca-key.pem -sha256 -out certs/root-ca.pem -config root-ca.cnf

openssl x509 -in certs/root-ca.pem -out certs/root-ca.crt -outform DER

# show ca contents 
openssl x509 -in certs/root-ca.pem -text

# create server private key
openssl genrsa -out certs/bytefusion-pkcs12-key.pem 2048

# convert key to pkcs8
openssl pkcs8 -v1 "PBE-SHA1-3DES" -in "certs/bytefusion-pkcs12-key.pem" -topk8 -out "certs/bytefusion-key.pem" -nocrypt

openssl req -new -key certs/bytefusion-key.pem -out certs/bytefusion.csr -config bytefusion.cnf


openssl x509 -req -in certs/bytefusion.csr -CA certs/root-ca.pem -CAkey certs/root-ca-key.pem -CAcreateserial -out certs/bytefusion.pem -sha256 -extensions extensions -extfile bytefusion.cnf

# show contents 
openssl x509 -in certs/bytefusion.pem -text