First, create your own internal CA.
You can use excellent Keystore Explorer tool for that and all the subsequent actions; feel free to translate it to OpenSSL commands.

Internal CA is really just a self-signed cert (keypair). Make sure to use proper extensions when creating it. At the very least, specify “Subject is a CA” in “Basic Constraints”.

Do not set CN in the subject so this keypair can never be used as a cert for actual domains.

CAs are allowed to have a long validity period, remember that you will need to reissue all the certs once the CA’s cert expires. However, we recommend limiting it to 5 years since you’d want to automate your cert provisioning anyway.

Keep your internal CA keypair in a separate keystore (Java) or in a completely separate place (ideally, in your centralized secrets/key manager). Never place the CA’s key in the same keystore with the certificate issued by this CA. Of course, the X509 of the CA could be widely distributed.

You can now start generating end-entity certs.

Create a new keypair (a self-signed cert) in the Keystore Explorer.

Your cert must have certain extensions, otherwise, it will be considered invalid, especially by mac OS browsers.

At the very minimum, it must include “Basic Constraints”, “Extended Key Usage”, “Key Usage”, “Subject Alternative Name” with the DNS names of your (internal) domains.

Note that browsers no longer trust the “CN” field and the “Subject Alternative Name” extension is a must.

The validity period cannot exceed 825 days, but the shorter the better. For internal certs, we recommend 90 days.

Now right-click on the new keypair and select “Generate new CSR”, save it to a file.

Now open the keystore with your local CA, right-click on the CA keypair and select “Sign CSR”. Remember that the private key is used for signing, whereas the signature can be validated with the CA’s public key (this how the whole certificate chain validation works)

Save the result in a p7r file which is a special format for CA’s responses. Do not forget to click on “Transfer extensions”, otherwise all the extensions in the original cert and in the CSR will be lost.

Now go back to the keystore with your self-signed cert keypair and select “Import response from CA”. Select the p7r file. You should now see your internal CA in the chain. Make sure that all the extensions are in place.

Save the keystore.

You can now import your internal CA into various browsers and when you navigate to your internal site, you should not see any security warnings.