Skip to main content

Root Certification Authority

CUIDADO En el actual libro queda pendiente solventar el problema de la generación de CRL en los certificados firmados. Algo MUY importante en un entorno PKI de producción. Para laboratorio / home se puede usar sin problemas, sin embargo no lo use para entorno IT de momento!

Inicializar estructura

Cree la estructura de directorios y ficheros que son necesarios para el funcionamiento de la PKI.

mkdir /root/ca
cd /root/ca
mkdir certs crl newcerts private
chmod 700 private
touch root-ca-database.txt
echo 1000 > serial
echo 1000 > crlnumber

A continuación cree el fichero de las politicas que va a usar la Root CA.

touch /root/ca/root-ca-openssl.cnf
nano /root/ca/root-ca-openssl.cnf

Copie el contenido y modifique el valor del apartado # Defaults req_distinguished_name indicando el nombre que desea que disponga la CA.

[ ca ]
# Indica que la policy a seguir esta en el apartado CA_default
default_ca = CA_default

[ CA_default ]
# Directory and file locations.
dir               	= /root/ca
certs             	= $dir/certs
crl_dir           	= $dir/crl
new_certs_dir     	= $dir/newcerts
database          	= $dir/root-ca-database.txt
serial            	= $dir/serial
RANDFILE          	= $dir/private/.rand

# The root key and root certificate.
private_key       	= $dir/private/root-ca.key.pem
certificate       	= $dir/certs/root-ca.cert.pem

# For certificate revocation lists.
crlnumber         	= $dir/crlnumber
crl               	= $dir/crl/ca.crl.pem
crl_extensions    	= crl_ext
default_crl_days  	= 365

# SHA-1 is deprecated, so use SHA-2 instead.
# Aumentamos a SHA512 para mayor seguridad y dificultad de colisiones.
default_md        	= sha512

name_opt          	= ca_default
cert_opt          	= ca_default

# Cambiamos la duración del certificado, es la Root CA... vamos a darle 16 años
# es menos seguro, pero también menos trabajo para IT y si tenemos desconectada +
# y bien guardada la Root CA no debería ser problema.
default_days      	= 5840
preserve          	= no
policy            	= policy_ca

[ policy_ca ]
countryName             = optional
stateOrProvinceName     = optional
localityName            = optional
organizationName        = optional
organizationalUnitName  = optional
commonName              = supplied
emailAddress            = optional

[ req ]
default_bits        	= 4096
distinguished_name  	= req_distinguished_name
string_mask         	= utf8only
default_md		= sha512

# Extension to add when the -x509 option is used.
x509_extensions     	= v3_ca

[ req_distinguished_name ]
countryName             = Country Name (2 letter code)
stateOrProvinceName     = State or Province Name
localityName            = Locality Name
0.organizationName      = Organization Name
organizationalUnitName  = Organizational Unit Name
commonName              = Common Name
emailAddress            = Email Address

# Defaults req_distinguished_name
countryName_default             = ES
stateOrProvinceName_default     = Barcelona
localityName_default            = Barcelona
0.organizationName_default      = GRG-ROOT-CA-2023
organizationalUnitName_default	= GRG-ROOT-CA-2023
#emailAddress_default           =

[ v3_ca ]
# Extensions for a typical CA (`man x509v3_config`).
subjectKeyIdentifier	= hash
authorityKeyIdentifier	= keyid:always,issuer
basicConstraints		= critical, CA:true
keyUsage		= critical, digitalSignature, cRLSign, keyCertSign

[ v3_intermediate_ca ]
# Extensions for a typical intermediate CA (`man x509v3_config`).
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always,issuer
basicConstraints = critical, CA:true
keyUsage = critical, digitalSignature, cRLSign, keyCertSign
crlDistributionPoints 	= root_crl_info

[ ocsp ]
# Extension for OCSP signing certificates (`man ocsp`).
basicConstraints	= CA:FALSE
subjectKeyIdentifier	= hash
authorityKeyIdentifier	= keyid,issuer
keyUsage		= critical, digitalSignature
extendedKeyUsage	= critical, OCSPSigning

[ crl_ext ]
# Extension for CRLs (`man x509v3_config`).
authorityKeyIdentifier	= keyid:always

[ root_crl_info ]
fullname = URI: http://pki.psc.lan/grg-root-ca-2023.crl,URI:http://pki.driverlandia.com/grg-root-ca-2023.crl,URI: http://ca.driverlandia.com/grg-root-ca-2023.crl

En este nivel no existe la CRL puesto que no tiene sentido que la ROOT CA tenga que consultar una CRL para ver si la han revocado a ella misma, ya que es la top de la entidad de Certificación.

Crear clave privada de la CA

La clave privada de la Root CA debe ser guardada y nunca! nunca! compartida, ya que es la única que puede revocar a todos los demás nodos y por lo tanto nunca debe ser comprometida. En caso de serlo, será necesario crear una nueva clave Root y volver a generar certificados para todos los dispositivos, con el consiguiente gasto de tiempo.

cd /root/ca
openssl genrsa -aes256 -out private/root-ca.key.pem 4096

Se le solicitará una contraseña. Genere una contraseña larga con algún programa tipo Bitwarden, Vaultwarden e introduzcala.

chmod 400 private/root-ca.key.pem

Crear certificado público de la CA

Ahora va a generar el certificado que identificará a la Root CA de forma pública. Asigne un a longitud larga para la validez del certificado, ya que si caduca el certificado, todos aquellos certificados firmados por Root CA y sus SubCA quedarán invalidados.

cd /root/ca
openssl req -config root-ca-openssl.cnf \
      -key private/root-ca.key.pem \
      -new -x509 \
      -days 5840 \
      -sha512 \
      -extensions v3_ca \
      -out certs/root-ca.cert.pem

Solicitará introducir la contraseña que hemos generado antes (para el fichero de clave privada). A continuación solicitará los datos que quiere que aparezcan en el certificado.

Finalmente modifique los permisos para que el certificado pueda ser leido.

chmod 444 certs/root-ca.cert.pem

Compruebe que los datos del certificado son correctos

openssl x509 -noout -text -in /root/ca/certs/root-ca.cert.pem

Opcional: Instale certificado

Puede instalar el certificado en la misma Root CA (ya que ella misma ha de fiarse de si misma), sin embargo si va a ser una máquina que siempre va a estar apagada y que no se ha de usar para nada mas que firmar la SUBCA cuando se haya caducado el certificado o haya sido comprometida.

cp /root/ca/certs/root-ca.cert.pem /etc/ssl/certs -v
ln -s /etc/ssl/certs/root-ca.cert.pem /usr/local/share/ca-certificates/root-ca.cert.pem
update-ca-certificates --fresh

Equipos del entorno

Ahora ya puede instalar dicho certificado en todos los equipos del entorno.

En los sistemas Linux puede usar Puppet o Ansible para desplegarlo.

En los sistemas Windows puede hacer uso de una GPO (si son equipos de dominio) para instalar el certificado en todos los equipos y hacer que confien en la entidad de certificación local. Previamente deberá convertir el certificado en formato PEM a formato CRT. (Cambie la extensión de .pem a .crt para que Windows lo reconozca)

Así cuando despliegue una web y la firme con un certificado de la PKI Interna, no saltará el mensaje de Certificado desconocido o Self-Signed.