User Tools

Site Tools


wiki:creating_ca_and_signing_server_and_client_certs_with_openssl

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Next revision
Previous revision
Next revisionBoth sides next revision
wiki:creating_ca_and_signing_server_and_client_certs_with_openssl [2021/04/15 13:29] – created antisawiki:creating_ca_and_signing_server_and_client_certs_with_openssl [2024/04/02 13:36] – [References] add client ssl cert links antisa
Line 17: Line 17:
   touch index.txt index.txt.attr   touch index.txt index.txt.attr
  
-Change the dir parameter in openssl.cnf to /tmp/myCA (no trailing slash!).+Change the dir parameter in openssl.cnf to /tmp/myCA (no trailing slash and use absolute path!).
  
 ===== Create the CA ===== ===== Create the CA =====
-==== Create CA private key ====+Generate CA private key with or without passphrase 
 + 
 +==== Create CA private key without passphrase ==== 
 +  openssl genrsa -out rootCA.key 4096 
 + 
 +==== Create CA private key with passphrase ====
   openssl genrsa -des3 -passout pass:qwerty -out  private/rootCA.key 2048   openssl genrsa -des3 -passout pass:qwerty -out  private/rootCA.key 2048
  
-==== Remove passphrase ====+==== Remove passphrase if needed ====
   openssl rsa -passin pass:qwerty -in private/rootCA.key -out private/rootCA.key   openssl rsa -passin pass:qwerty -in private/rootCA.key -out private/rootCA.key
  
Line 29: Line 34:
  
   openssl req -config openssl.cnf -new -x509 -subj '/C=DE/L=City/O=MyORG/CN=somename' -days 3650 -key private/rootCA.key -out certs/rootCA.crt   openssl req -config openssl.cnf -new -x509 -subj '/C=DE/L=City/O=MyORG/CN=somename' -days 3650 -key private/rootCA.key -out certs/rootCA.crt
 +
 +Or you can have openssl prompt you for the info with this command:
 +  openssl req -new -x509 -days 3650 -sha256 -key private/rootCA.key -out certs/rootCA.crt
  
 ===== Create a SSL Server certificate ===== ===== Create a SSL Server certificate =====
-==== Create private key for the server ====+ 
 +==== Create private key for the server without passphrase ==== 
 +  openssl genrsa -out private/server.key 2048 
 + 
 +==== Create private key for the server with passphrase ====
   openssl genrsa -des3 -passout pass:qwerty -out private/server.key 2048   openssl genrsa -des3 -passout pass:qwerty -out private/server.key 2048
  
Line 40: Line 52:
 ==== Create CSR for the server. Change CN. ==== ==== Create CSR for the server. Change CN. ====
   openssl req -config openssl.cnf -new -subj '/C=DE/L=City/O=MyORG/CN=someothername' -key private/server.key -out csr/server.csr   openssl req -config openssl.cnf -new -subj '/C=DE/L=City/O=MyORG/CN=someothername' -key private/server.key -out csr/server.csr
 +
 +Or interactively
 +  openssl req -new -sha256 -key private/server.key -out csr/server.csr
  
 ==== Create certificate for the server ==== ==== Create certificate for the server ====
Line 45: Line 60:
   openssl ca -batch -config openssl.cnf -days 3650 -in csr/server.csr -out certs/server.crt -keyfile private/rootCA.key -cert certs/rootCA.crt -policy policy_anything   openssl ca -batch -config openssl.cnf -days 3650 -in csr/server.csr -out certs/server.crt -keyfile private/rootCA.key -cert certs/rootCA.crt -policy policy_anything
  
 +Alternatively with a custom provided config file
 +  openssl ca -config mycustom-config.conf -cert certs/rootCA.crt -keyfile private/rootCA.key -in csr/server.csr -out certs/server.crt
 +
 +Contents of //mycustom-config.conf//:
 +<code>
 +[ ca ]
 +default_ca              = Practical-TLS_CA-config
 +
 +[ Practical-TLS_CA-config ]
 +dir                     = RootCA/CA
 +certs                   = $dir
 +new_certs_dir           = $dir
 +database                = $dir/index.txt
 +serial                  = $dir/serial
 +default_days            = 365
 +default_crl_days        = 30
 +default_md              = sha256
 +preserve                = no
 +copy_extensions         = copy
 +policy                  = DN_attributes
 +x509_extensions         = certificate_extensions
 +
 +[ DN_attributes ]
 +countryName             = optional
 +stateOrProvinceName     = optional
 +localityName            = optional
 +organizationName        = optional
 +organizationalUnitName  = optional
 +commonName              = supplied
 +emailAddress            = optional
 +
 +[ certificate_extensions ]
 +basicConstraints        = CA:FALSE
 +subjectKeyIdentifier    = hash
 +authorityKeyIdentifier  = keyid,issuer
 +keyUsage                = digitalSignature, keyEncipherment
 +extendedKeyUsage        = serverAuth
 +
 +</code>
 ===== Create a SSL Client certificate ===== ===== Create a SSL Client certificate =====
 +
 +<WRAP center round tip 60%>
 +To use the client certificate in Firefox you need to export it to the correct format like so
 +
 +  openssl pkcs12 -export -in certs/client.crt -inkey private/client.key -out certs/client.p12
 +
 +Then you can import it via Settings > Security > View certificates > Import.
 +Also the server config needs to be added, e.g. for nginx
 +  server {
 +  ...
 +  ssl_verify_client on;
 +  ssl_client_certificate /etc/nginx/rootCA.crt;
 +  ...
 +</WRAP>
 +
 +==== Create private key for the client without passphrase ====
 +  openssl genrsa -out private/client.key 2048
 +
 ==== Create private key for a client ==== ==== Create private key for a client ====
  
Line 51: Line 123:
  
 ==== Remove passphrase ==== ==== Remove passphrase ====
- +
   openssl rsa -passin pass:qwerty -in private/client.key -out private/client.key   openssl rsa -passin pass:qwerty -in private/client.key -out private/client.key
  
Line 58: Line 130:
   openssl req -config openssl.cnf -new -subj '/C=DE/L=City/O=MyORG/CN=thirdname' -key private/client.key -out csr/client.csr   openssl req -config openssl.cnf -new -subj '/C=DE/L=City/O=MyORG/CN=thirdname' -key private/client.key -out csr/client.csr
  
 +Or interactively
 +  openssl req -new -sha256 -key private/client.key -out csr/client.csr
 ==== Create client certificate. ==== ==== Create client certificate. ====
  
Line 67: Line 141:
   openssl verify -CAfile certs/rootCA.crt certs/server.crt   openssl verify -CAfile certs/rootCA.crt certs/server.crt
  
 +To inspect the CSR you can run:
 +  openssl req -in client.csr -noout -text
 +
 +To inspect the certificate:
 +  openssl x509 -in client.crt -noout -text
 +
 +To inspect the key:
 +  openssl rsa -in client.key -noout -text
 +
 +===== Additional extensions =====
 +If you need to add some x509 certificate extensions. like Subject Alternative Name (SAN) for additional domains you can provide a config file to the CSR similar to this:
 +
 +//mycsr.conf//:
 +
 +<code>
 +
 +[ req ]
 +distinguished_name  = requested_distinguished_name
 +req_extensions = requested_extensions
 +
 +[ requested_distinguished_name ]
 +countryName                     = Country Name (2 letter code)
 +stateOrProvinceName             = State or Province Name (full name)
 +localityName                    = Locality Name (eg, city)
 +organizationName                = Organization Name (eg, company)
 +commonName                      = Common Name
 +
 +countryName_default             = HR
 +stateOrProvinceName_default     = North Province
 +localityName_default            = The Town
 +organizationName_default        = Secret org
 +
 +[ requested_extensions ]
 +subjectAltName = @list_of_alternative_names
 +
 +[ list_of_alternative_names ]
 +DNS.1   = example.com
 +DNS.2   = en.admin.example.com
 +DNS.3   = fr.admin.example.com
 +DNS.5   = es.admin.example.com
 +DNS.6   = mywebsite.com
 +DNS.7   = *.mywebsite.com
 +DNS.8   = lol.com
 +DNS.9   = *.lol.com
 +
 +</code>
 +Above configuration will prompt you for commonName, organizationName etc. If you want to avoid prompting use below configuration:
 +
 +<code>
 +[ req ]
 +default_bits           = 2048
 +default_keyfile        = keyfile.pem
 +distinguished_name     = req_distinguished_name
 +attributes             = req_attributes
 +prompt                 = no
 +output_password        = mypass
 +
 +[ req_distinguished_name ]
 +C                      = GB
 +ST                     = Test State or Province
 +L                      = Test Locality
 +O                      = Organization Name
 +OU                     = Organizational Unit Name
 +CN                     = Common Name
 +emailAddress           = test@email.address
 +
 +[ req_attributes ]
 +
 +</code>
 +Note that the **prompt=no**, different attribute names in **req_distinguished_name** and empty **req_attributes** part.
 +<WRAP center round info 60%>
 +You cannot define *_min, *_max and *_default when prompt is set to no.
 +</WRAP>
 +
 +<WRAP center round info 60%>
 +Defining Organization Name, Locality etc. will not work with Letsencrypt. O and OU are only used for organization validation certificates. Let’s Encrypt only offers domain validation and can’t make any assertion as to the person or company that owns/manages the domain.
 +</WRAP>
 +
 +
 +Then after generating the key
 +  openssl genrsa -out private/client.key 2048
 +create the CSR
 +  openssl req -new -sha256 -config mycsr.conf -key private/client.key -out csr/client.csr
 ====== Tested on ====== ====== Tested on ======
-  * Ubuntu 18.04+  * Ubuntu 18.04, 20.04.04 
 +  * stunnel
  
 ====== See also ====== ====== See also ======
 +  * [[wiki:openssl_commands|Openssl commands]]
 ====== References ====== ====== References ======
   * http://theheat.dk/blog/?p=1023   * http://theheat.dk/blog/?p=1023
 +  * [[https://community.letsencrypt.org/t/organization-o-and-organizational-unit-ou-in-field-issued-to/5236|Letsencrypt does not support O, OU etc. fields in certificates]]
 +  * https://github.com/openssl/openssl/issues/11287#issuecomment-811483183
 +  * https://www.openssl.org/docs/man1.1.1/man1/req.html
 +  * https://groups.google.com/g/mailing.openssl.users/c/kdCLWzJ5w1I
 +  * https://www.ssltrust.com.au/help/setup-guides/client-certificate-authentication
 +  * https://pavelevstigneev.medium.com/setting-nginx-with-letsencrypt-and-client-ssl-certificates-3ae608bb0e66
  
wiki/creating_ca_and_signing_server_and_client_certs_with_openssl.txt · Last modified: 2024/04/09 14:08 by antisa

Except where otherwise noted, content on this wiki is licensed under the following license: CC0 1.0 Universal
CC0 1.0 Universal Donate Powered by PHP Valid HTML5 Valid CSS Driven by DokuWiki