Skip to main content

Root Certification Authority

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

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

Se ha cambiado el SHA256 por SHA512, el valor de default_crl_days a 365, el valor de default_days a 5840 y algunos settings del apartado req_distinguished_name.

Parámetro Valor default Nuevo valor Motivo
default_md sha256 sha512 Reducir el riesgo de colision de hash y
por lo tanto aumentar su seguridad
default_bits 2048 4096 Aumentar la seguridad del certificado
default_crl_days 30 365 Evitar tener que generar una CRL cada més
default_days 375 5840 Evitar tener que generar el certificado root cada año
URI.0 No existia Ruta CRL primaria Ruta donde consultar si las Subca han sido revocadas
URI.1 No existia Ruta CRL secundaria Ruta donde consultar si las Subca han sido revocadas

Revise el contenido y copielo en su fichero de configuración (root-ca-openssl.cnf).

root-ca-openssl.conf ```
[ 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

# Modificamos el nombre del fichero de la base de datos que hemos creado antes

database = $dir/root-ca-database.txt serial = $dir/serial RANDFILE = $dir/private/.rand

# The root key and root certificate.

private_key = $dir/private/ca.key.pem certificate = $dir/certs/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_strict

[ policy_strict ]

# The root CA should only sign intermediate certificates that match.

# La idea es que la Root CA solo sirva para firmar SUBCA de la misma empresa

# sin embargo si queremos tener varias subCA, podemos poner el Organization Name y otros

# parametros como optional

countryName = match stateOrProvinceName = match organizationName = match organizationalUnitName = optional commonName = supplied emailAddress = optional

[ policy_loose ]

# Allow the intermediate CA to sign a more diverse range of certificates.

# See the POLICY FORMAT section of the ca`ca` man page.

countryName = optional stateOrProvinceName = optional localityName = optional organizationName = optional organizationalUnitName = optional commonName = supplied emailAddress = optional

[ req ]

# Options for the req`req` tool (`man reqreq`).

default_bits = 4096 distinguished_name = req_distinguished_name string_mask = utf8only

# SHA-1 is deprecated, so use SHA-2 instead.

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

# Optionally, specify some defaults.

countryName_default = ES stateOrProvinceName_default = Barcelona localityName_default = Barcelona 0.organizationName_default = GRG-CA #organizationalUnitName_default = #emailAddress_default =

[ v3_ca ]

# Extensions for a typical CA (`man x509v3_configx509v3_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_configx509v3_config`).

subjectKeyIdentifier = hash authorityKeyIdentifier = keyid:always,issuer basicConstraints = critical, CA:true, pathlen:0 keyUsage = critical, digitalSignature, cRLSign, keyCertSign

[ usr_cert ]

# Extensions for client certificates (`man x509v3_configx509v3_config`).

basicConstraints = CA:FALSE nsCertType = client, email nsComment = "OpenSSL Generated Client Certificate" subjectKeyIdentifier = hash authorityKeyIdentifier = keyid,issuer keyUsage = critical, nonRepudiation, digitalSignature, keyEncipherment extendedKeyUsage = clientAuth, emailProtection

[ server_cert ]

# Extensions for server certificates (`man x509v3_configx509v3_config`).

basicConstraints = CA:FALSE nsCertType = server nsComment = "OpenSSL Generated Server Certificate" subjectKeyIdentifier = hash authorityKeyIdentifier = keyid,issuer:always keyUsage = critical, digitalSignature, keyEncipherment extendedKeyUsage = serverAuth

[ ocsp ]

# Extension for OCSP signing certificates (`man ocspocsp`).

basicConstraints = CA:FALSE subjectKeyIdentifier = hash authorityKeyIdentifier = keyid,issuer keyUsage = critical, digitalSignature extendedKeyUsage = critical, OCSPSigning

[ crl_ext ]

# Extension for CRLs (`man x509v3_configx509v3_config`).

authorityKeyIdentifier=keyid:always

[ crl_info ] URI.0 = http://pki.driverlandia.com/root-ca.crl URI.1 = https://www.driverlandia.com/pki/root-ca.crl

La CRL no tiene porqué estar alojada en el mismo servidor que las CA, sin embargo si que deben ser accesibles para todos los equipos del entorno. Si hay equipos que se conectan desde otra ruta de Internet (sin VPN), siempre se puede añadir una segunda ruta accesible desde internet para que se pueda consultar la CRL.

Solo será necesario recordar actualizar dichas rutas cada vez que se genere una nueva CRL.

</details>
###

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 7300
\ -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 certs/root-ca.cert.pem

[![](https://docs.driverlandia.com/uploads/images/gallery/2022-10/scaled-1680-/1EHGP5iIpgRwboNY-image-1665232417543.png)](https://docs.driverlandia.com/uploads/images/gallery/2022-10/1EHGP5iIpgRwboNY-image-1665232417543.png) <details> <summary>Opcional: Instale certificado</summary>

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

</details>