Skip to content

Instantly share code, notes, and snippets.

@hellp
Last active August 29, 2015 14:05
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save hellp/fd45862cd75114702e3a to your computer and use it in GitHub Desktop.
Save hellp/fd45862cd75114702e3a to your computer and use it in GitHub Desktop.
How to create a self-signed root CA certificate

To access and sync my Owncloud's calendar and contacts with my Android phone in a (more-or-less) secure manner through HTTPS, I needed to get a SSL/TLS certificate. Or precisely: a self-signed root CA (Certification Authority) certificate.

After searching for Howtos and creating a bunch of CA certificates, normal certificates, signing them, signing them vice-versa etc. -- yes, I don't really have a clue -- I mostly run into one of these errors:

  • when signing normal cert with CA cert: "not self-signed"
  • when self-signing normal cert with itself: "no Basic Constraint CA flag"

Then I finally found (https://langui.sh/2009/01/18/openssl-self-signed-ca/) this one-liner that does the job just fine:

$ openssl req -newkey rsa:2048 -days 365 -x509 -nodes -out root.cer

Make sure to use the domain name you want to use this certificate on as the Common Name (CN).

This creates a certificate file (named as defined in the -out parameter) and a key file, named 'privkey.pem' in my case. I had to upload this in the admin interface of my shared hoster, and 5 minutes later the certificate was installed and accepted by DAVDroid, the Android syncing app.

Tags: owncloud, https, security, webdav, caldav, carddav, openssl, ubuntu, linux

@pilif
Copy link

pilif commented Aug 25, 2014

I would recommend you extend the expiration of your root by a lot (and maybe use a 4096 bit key)

There's no official way to extend a root certificate, so after a year (using your command line above), you'll have to redistribute the new root to all clients and you'll basically limit the lifetime of all certificates issued by your root to the lifetime of the root itself (one year).

@hellp
Copy link
Author

hellp commented Aug 25, 2014

Thanks for the hints. I actually thought about that. The one-liner was pretty much copy-pasted, although I understand what it does now.

I'll definitely increase the size.

I'm not sure about the expiration: I only use the certificate myself and won't issue and sign other certificates with it. Isn't it more secure (albeit a bit of work, of course) to trash a certificate from time to time?

@pilif
Copy link

pilif commented Aug 25, 2014

About the expiration, if you expire actual service certificates after 1-2 years, that's common practice, though, again, I'm not so sure whether even that's needed in case of a self-signed certificate.

The idea behind adding the expiration on public certificates is twofold:

  1. There's financial incentive to have them expire after some time because that allows the CA to charge you again after some time has past
  2. Considering that the various methods for tracking certificate revocation don't all work very well (CRL doesn't really scale, OCSP has privacy concerns, OCSP stapling is optional and OCSP-must-staple isn't widely supported yet), by having the certificates expire after some time, you get a "free" built-in revocation no matter if the other methods work or not.

The third point would be that it forces a specific ceiling after which an attacker who brute-forced or otherwise obtained the certificate can actually use it (if you fail to find out about the breach or all revocation methods fail (see 2 above)), but if you really fail to detect a breach and subsequent loss of your certificate (we can totally ignore the brute-force approach for now) within a year, then you have different issues than an invalid certificate I guess.

As such I would say that even for private services (CAs are different - see next section), a much longer expiration isn't much less secure but way, way more convenient.

For CAs, things look different: Certificate validation is applied to the whole chain, so even if your service expires, say, two years from now, if the CA's certificate expires tomorrow, then tomorrow is when clients stop connecting to your service.

This means that the maximum length of any certficate issued by a CA is constrained by the expiration of the CA's certificate.

Additionally, there's a deployment issue: For CAs signed by a CA to be recognized by clients, that CA certificate has to be deployed to the clients. In case of the official public CAs, that's done using the browser vendor (and you'll notice that they all expire far-in-the-future), but in case of your private CA, you'll have to deploy the certificate manually to the clients.

So while refreshing a service certificate is something you do once on the server (provided the CA certificate is still valid), refreshing a CA certificate means re-deploying the new certificate to all clients.

When you consider that the number of clients will increase over time (hopefully), you'll increase that burden more and more as time progresses.

This led me to my recommendation to have the CA certificate expire far in the future but let the service certificate expire somewhat sooner (if you want).

The big public CAs use a system of intermiediate certificates for this purpose: The root (whose public key is shipped with every browser) expires far, far in the future (2050ish or even later), but the private key of that root isn't available online but only stored in some HSM which in turn is offline and stored in some bank vault (I would hope!).

Then, using that certificate, they sign an intermediate which they then use to sign actual customer certificates. These intermediates also expire far-ish in the future (10ish years), but at least as far as the longest expiration they offer to a customer because they can't reasonably ask customers to update the certificate they bought mid-term just because the intermediate has expired.

Once the expiration of the intermediate is closer than the longest leaf certificate they hand out, they will create a new intermediate and have that signed by that super-secret only offline-available root certificate. Yes, that's annyoing and difficult, but when you only have to do it once every 10ish years, I guess that's an ok trade-off).

But back to your private CA, here's my recommendation:

  1. Issue the CA certificate with a very long expiration but don't go the extra length to put it on some HSM in some back account.
  2. Issue Leaf certificates directly with that CA certificate and have them expire in 5-10 years (in my case: For services, I use 10 years, but for client-access via OpenVPN, I use only 1 year)
  3. Deploy the CA certificate to your clients.

That way you won't have to re-deploy a certificate any time soon (which is the annoying and time-intensive part) while you can still update the leaf certificates as often as you want.

This was a bit of a long explanation. Sorry. But I hope, you still can get some value out of this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment