How To Create Your Own Certification Authority (CA)

  1. Create the CA's certificiate.

    1. Create a file with the CA's certificate configuration (see req(1) configuration format) ca.conf:

      [req] # Request section
      default_bits = 4096 # Private key length
      default_keyfile = ca.key # Destination of private key
      encrypt_key = no # Do not use password for cyphering private key
      default_md = sha256 # Sign using digest
      x509_extensions = v3_req # Section with extensions
      prompt = no # Do not ask for distinguished name attributes, use those in this file
      utf8 = yes # Enable use of extended character set
      distinguished_name = req_distinguished_name # Distinguished name section
      
      [req_distinguished_name] # Distinguished name section
      C = MX # Country code
      ST = Estado de México # State
      L = MEX # Locality or city
      O = WAKE # Organization
      OU = ITSEC # Organization department or unit
      CN = WAKE CA V1 # Common name
      emailAddress = itsec@wake.mx # Subject's email
      
      [v3_req] # Extension section
      basicConstraints = CA:TRUE # Certificate will belong to a Certification Authority
      keyUsage = digitalSignature,nonRepudiation,keyCertSign # Intended uses of key
      # subjectAltName is optional for a CA, along with its alt_names section
      subjectAltName = @alt_names # Section for Subject Alternative Names
      
      [alt_names] # Subject Alternative Names section
      DNS.1 = ca.wake.mx
    2. Create the private key and the actual certificate.
      openssl req -x509 -config ca.conf -days 3650 > ca.crt
    3. Optionally verify the created certificate details.
      openssl x509 -noout -text -in ca.crt
  2. Add new certificate ca.crt to OS's trusted roots. In macOS:
    1. Open Keychain Access.
    2. Choose from Keychains: login (for user trusted certs) or System Roots (for system-wide trusted certs).
    3. Choose Certificates from the Category section.
    4. Drag and drop ca.crt into the listing.
    5. Input admin credentials when prompted.
    6. Right-click over new certificate.
    7. Click Get Info.
    8. Unfold Trust section.
    9. Choose Always Trust from the When using this certificate: dropdown menu.
    10. Close window and enter admin credentials as prompted.
    11. Quit Keychain Access.
  3. Use the new CA's certificate to sign a Certificate Signing Request (CSR). In the end, this is what CAs do.

    1. Create a configuration file client.conf for a new CSR:

      [ req ] # Request section
      default_bits = 4096 # Private key length
      default_keyfile = client.key # Private key destination file
      encrypt_key = no # Should use passphrase for cyphering private key
      default_md = sha256 # Digest to use for requested certificate
      req_extensions = req_ext # Request extensions area
      prompt = no # Should prompt for distinguished name attributes
      utf8 = yes # Should allow special characters
      distinguished_name = req_distinguished_name # Distinguished name section
      
      [ req_distinguished_name ] # Distinguished name section
      C = MX # Country code
      ST = CDMX # State
      L = MEX # Locality or city
      O = JYSA # Organization
      OU = ITSEC # Organization's department or unit
      CN = JYSA con tílde # Common name
      emailAddress = jysa@wake.services # Subject's email
      
      [ req_ext ] # Extensions section
      subjectAltName = @alt_names # Subject alternative names section
      
      [alt_names] # Subject alternative names section
      DNS.1 = jysa.wake.services # FQDN
      DNS.2 = *.jysa.wake.mx # Wildcard domain
    2. Create the actual CSR.
      openssl req -new -config client.conf > client.csr
    3. Create and sign the client's certificate, using its CSR, with the CA's certificate.
      openssl x509 -req -in client.csr -CA ca.crt -CAkey ca.key -days 365 -CAcreateserial -SHA256 -extfile client.conf -extensions req_ext > client.crt

Notes

  1. Google Chrome will not trust certificates without the Subject Alternative Name section.
  2. Google Chrome will not trust certificates signed with SHA-1 algorithm. Use SHA256.

References

  1. Chrome's SAN Imposition
  2. OpenSSL Default Configuration File
  3. Certificate Decoder
  4. How to Sign a CSR
  5. openssl req(1)
  6. x509v3_config(5)
  7. openssl x509(1)
  8. Tutorial
  9. Tutorial
  10. Tutorial
  11. Tutorial
  12. Tutorial