Do not issue certificates for long time periods, renew them often. This is similar to renewing passwords, it helps limit the damage from any potentially compromised key. The process to refresh keys/certificates must be fully automated, otherwise a frequent renewal cycle is not going to be practical. Many organizations issue internal certificates for 12 or 24 months simply because they have manual and laborious processes to install new certificates. This creates a great security risk. Should a certificate/key get compromised, a perpetrator would be able to use if for long time. A certificate revocation/OCSP process can help mitigating this, unfortunately, CRL/OCSP is rarely implemented for internal CAs (let alone for self-signed certs).
The optimal validity period mostly depends on the degree of automation. With a fully automated issuance and provisioning process, there is no reason why internal certificate/key pair cannot be rotated on a daily or even more frequent basis without causing any disruption.
Certificate revocation/CLR can work as well in the internal setting if properly configured.
If there no OCSP/revocation mechanism in place, limit the certificate trust. Do not make all of your components trust a single internal CA that issued all the certificates. Establish the trust at the individual interfaces level (e.g., server A communicates with the server B, so the server A needs to trust the cert from the server B but not its CA).
Automation is the only viable and reliable way to implement a truly secure certificate management processes. Automation allows for frequent certificate/key rotation, easy enforcement of all the certificate policies (including the ones described in this document), full visibility and control.
An automated process ideally should provide all of the CA functions plus certificate distribution and installation.
The automated installation routine should allow for distributing a particular cert to all the instances (containers, VMs, etc.) constituting a given service.
Self-signed certs have no provenance. Anyone can create them. There is no CA to consult the validity of the cert (e.g., via OCSP). It is hard to enforce various policies for self-signed certs, such as the signature type, the key length, etc. Self-signed certs provide no audit trail and no journaling similar to the ones mandated by Google’s certificate transparency standard.
There are many security scanners that scan ports and pre-defined endpoints. However, it is also important to look inside Java keystores, PEM files and all the other artifacts containing crypto material that are bundled inside applications and may not be discoverable by a scanning process. For example, there is no way to identify SSL client certificates just by running an endpoint scanner.
Having a complete inventory of all active certificate/keys, including their location on disk, is extremely important. This allows for efficiently dealing with compromised certs, this is also the first step towards automating the certificate/key management process.
Many organizations have heavy-weight application/security scanning process which takes a while run. The result of the scan is often a voluminous report that takes a while to go through and act upon. Thus the scan runs infrequently.
Certificate scanning on the other hand can be very quick. It can also be paired with the automated refresh process so that the certificates/keys close to their expiration are automatically refreshed.
Many databases and messaging products use TLS over TCP (as opposed to HTTP). This includes SQL Server, Oracle, ActiveMQ, etc. It’s more difficult to checkOld TCP endpoints and some security scanners do not have good support for them.
Make sure that you have an inventory of all non-HTTP endpoints and their certificates; their scanning should be part of a regular scanning process.
Keys must always be protected by a password. Applications should not stored these passwords in plain text.
For Java/JVM-based applications, keystore files serve as the de-facto “secrets repository” (for better or worse). Please follow our keystore best practices for the specific recommendations on keystore management.
Root certificates/keys used for issuing other certificates must be guarded with special care, access to these files must be strictly controlled.
Certificates determine trust relationships between components, at least at the transport level. First and foremost, we need to understand the data flows in our system and regulate trust accordingly. Let’s say a service A invokes a service B, which in turn invokes a service C. “A” must trust the certificate from “B”, but not necessarily from “C”. If “C” is compromised, we don’t need to worry notifying “A” about the certificate revocation or about removing the compromised cert from “A” altogether.
Granted, it is much easier to deploy an internal CA cert to all services so that all trust all but this is certainly a less secure approach. This approach is advisable only if there is a solid internal certificate validation/revocation process in place.
When certificate deployment is fully automated, point-to-point trust at a service level is easily implemented .
Limit the number of CAs that you allow to trust by default. All Linux distros come pre-populated with many well-known public CAs and many Linux tools and applications blindly trust all the CAs from “/etc/ssl/certs”. Java clients trusts all public CAs by default (since they are contained in the “cacerts” default keystore).
For calls to internal components it is more secure to setup an internal CA and then permit trust only for certificates issued by that CA.
For external calls, establish trust at the domain (end entity level) as opposed to an CA that issued the end-entity’s certificate.