If your infrastructure is tiny, much of the details of running a CA (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 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.cer
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.