How do I create a CA intranet?
need to create my own CA for an intranet and unfortunately it seems there's no good answer about this on Security.SE. There are many resources online about this, but all of them are different and some use outdated defaults (MD5/SHA1, etc) which doesn't seem that trustworthy. There are also hundreds of different variations of openssl.cnf, ranging from a 10-line file to the enormous one that came by default with my distribution.
I would like a canonical answer about setting up a simple CA for issuing server certs and client certs. Apparently it seems some people still don't understand that I'm not some large company where a CA compromise causes billions worth of losses and can't be mitigated easily so let me explain a bit better why I need the CA :multiple servers connected via insecure links (the Internet) need to communicate securely. I need a way to identify myself to those servers in order to perform administrative tasks, without going back and forth to my password manager every 10 seconds.
no other CAs than mine should be able to impersonate any of the servers, no matter how unlikely (but possible) that is. There. My own PKI and a cert installed on each machine seems to fit the needs perfectly. One of the software I use also requires the use of a PKI, so just using self-signed certificates isn't an option.
To compromise the PKI someone would need to compromise my work machine, and if that's done then the attacker can already do quite a bit of damage without even touching the PKI (as I would be logging in via SSH to the server from this machine anyway). That is a risk I'm accepting to take, and this PKI doesn't add any more risk than what there is already.
If your infrastructure is tiny, much of the details of running a CA Intranet (e.g. CRLs and such) can probably be ignored. Instead, all you really have to worry about is signing certificates.
There's a multitude of tools out there that will manage this process for you. I even wrote one many years ago. But the one I recommend if you want something really simple is easy-rsa from the OpenVPN project. It's a very thin wrapper around the OpenSSL command-line tool. If you're going to be managing a LOT of certificates and actually dealing with revocation and stuff, you'll want a much more complex and feature-complete utility. There are more than enough suggestions already provided, so instead I'll just stick with the basics of what you're trying to accomplish. But here's the basic procedure. I'll explain it with OpenSSL, but any system will do. Start by creating your "root" CA -- it'll be a self-signed certificate. There are several ways to do this; this is one. We'll make ours a 10-year cert with a 2048-bit key. Tweak the numbers as appropriate. You mentioned you were worried about the hashing algorithm, so I added -sha256 to ensure it's signed with something acceptable. I'm encrypting the key using AES-256, but that's optional. You'll be asked to fill out the certificate name and such; those details aren't particularly important for a root CA.
# First create the key (use 4096-bits if that's what floats your boat)
openssl genrsa -aes256 -out root.key 2048
# Then use that key to generate a self-signed cert
openssl req -new -x509 -key root.key -out root.cer -days 3652 -sha256
If you encrypted the key in the first step, you'll have to provide the password to use it in the second. Check your generated certificate to make sure that under "Basic Constraints" you see "CA: TRUE". That's really the only important bit you have to worry about: openssl x509 -text < root>
Cool. OK, now let's sign a certificate. We'll need another key and this time a request. You'll get asked about your name and address again. What fields you fill in and what you supply is up to you and your application, but the field that matters most is the "Common Name". That's where you supply your hostname or login name or whatever this certificate is going to attest.
# Create new key
openssl genrsa -aes256 -out client1.key 2048
# Use that key to generate a request
openssl req -new -key client1.key -out client1.req
# Sign that request to generate a new cert
openssl x509 -req -in client1.req -out client1.cer -CA root.cer -CAkey root.key -sha256 -CAcreateserial
Note that this creates a file called root.srl to keep our serial numbers straight. The -CAcreateserial flag tells openssl to create this file, so you supply it for the first request you sign and then never again. And once again, you can see where to add the -sha256 argument. This approach -- doing everything manually -- is in my opinion not the best idea. If you're running a sizable operation, then you'll probably want a tool that can keep track of all your certificates for you.
Instead, my point here was to show you that the output you want -- the certificates signed the way you want them -- is not dependent on the tools you use, but rather the options you provide to those tools. Most tools can output a wide variety of configurations, both strong and weak, and it's up to you to supply the numbers you deem appropriate. Outdated defaults are par for the course.