En criptografía una autoridad de certificación, certificadora o certificante (AC o CA por sus siglas en inglés Certification Authority) es una entidad de confianza, responsable de emitir y revocar los certificados digitales o certificados, utilizados en la firma electrónica, para lo cual se emplea la criptografía de clave pública. Jurídicamente es un caso particular de Prestador de Servicios de Certificación.
La Autoridad de Certificación, por sí misma o mediante la intervención de una Autoridad de Registro, verifica la identidad del solicitante de un certificado antes de su expedición o, en caso de certificados expedidos con la condición de revocados, elimina la revocación de los certificados al comprobar dicha identidad. Los certificados son documentos que recogen ciertos datos de su titular y su clave pública y están firmados electrónicamente por la Autoridad de Certificación utilizando su clave privada.
Certificado raiz
Preparación del escenario
Creamos el directorio raíz mkdir /root/ca
y la estructura de directorios. Los archivos index.txt
y serial actúan como una base de datos de archivos planos para realizar un seguimiento de los certificados firmados.
# cd /root/ca # mkdir certs crl newcerts private # chmod 700 private # touch index.txt # echo 1000 > serial
Creación fichero de configuración openssl.cnf
Debemos crear un fichero de configuración /root/ca/openssl.cnf
el cual vamos a rellenar con lo siguiente:
# OpenSSL root CA configuration file. # Copy to `/root/ca/openssl.cnf`. [ ca ] # `man ca` 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/index.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 = 30 # SHA-1 is deprecated, so use SHA-2 instead. default_md = sha256 name_opt = ca_default cert_opt = ca_default default_days = 375 preserve = no policy = policy_strict [ policy_strict ] # The root CA should only sign intermediate certificates that match. # See the POLICY FORMAT section of `man ca`. 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` man page. countryName = optional stateOrProvinceName = optional localityName = optional organizationName = optional organizationalUnitName = optional commonName = supplied emailAddress = optional [ req ] # Options for the `req` tool (`man req`). default_bits = 2048 distinguished_name = req_distinguished_name string_mask = utf8only # SHA-1 is deprecated, so use SHA-2 instead. default_md = sha256 # Extension to add when the -x509 option is used. x509_extensions = v3_ca [ req_distinguished_name ] # See <https://en.wikipedia.org/wiki/Certificate_signing_request>. 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 = GB stateOrProvinceName_default = England localityName_default = 0.organizationName_default = Alice Ltd organizationalUnitName_default = 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, pathlen:0 keyUsage = critical, digitalSignature, cRLSign, keyCertSign [ usr_cert ] # Extensions for client certificates (`man x509v3_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_config`). basicConstraints = CA:FALSE nsCertType = server nsComment = "OpenSSL Generated Server Certificate" subjectKeyIdentifier = hash authorityKeyIdentifier = keyid,issuer:always keyUsage = critical, digitalSignature, keyEncipherment extendedKeyUsage = serverAuth [ crl_ext ] # Extension for CRLs (`man x509v3_config`). authorityKeyIdentifier=keyid:always [ ocsp ] # Extension for OCSP signing certificates (`man ocsp`). basicConstraints = CA:FALSE subjectKeyIdentifier = hash authorityKeyIdentifier = keyid,issuer keyUsage = critical, digitalSignature extendedKeyUsage = critical, OCSPSigning
Creamos clave privada para la entidad certificadora
Ahora vamos a crear el certificado para la entidad certificadora primero creamos la clave privada
# cd /root/ca # openssl genrsa -aes256 -out private/ca.key.pem 4096 Enter pass phrase for ca.key.pem: ********* Verifying - Enter pass phrase for ca.key.pem: ********* # chmod 400 private/ca.key.pem
Creamos certificado raiz de la entidad certificadora
Utilizamos la clave raíz ca.key.pem
para crear un certificado raíz ca.cert.pem
. Proporcione al certificado raíz una fecha de caducidad larga, como veinte años. Una vez que expire el certificado raíz, todos los certificados firmados por la entidad emisora serán inválidos.
# cd /root/ca # openssl req -config openssl.cnf \ -key private/ca.key.pem \ -new -x509 -days 7300 -sha256 -extensions v3_ca \ -out certs/ca.cert.pem Enter pass phrase for ca.key.pem: secretpassword You are about to be asked to enter information that will be incorporated into your certificate request. ----- Country Name (2 letter code) [XX]:ES State or Province Name []:Sevilla Locality Name []: Organization Name []:[Nombre de tu organizacion] Organizational Unit Name []:[Nombre de tu organizacion] Common Name []:[Nombre de tu organizacion] Email Address []:[Correo electronico] # chmod 444 certs/ca.cert.pem
Creamos un certificado intermedio
El motivo principal del certificado intermedio es tener mas seguridad. Si la clave intermedia está comprometida, la entidad emisora de certificados raíz puede revocar el certificado intermedio y crear un nuevo par criptográfico intermedio.
Preparar el escenario
Creamos el directorio raíz mkdir /root/ca/intermediate
y la estructura de directorios. Los archivos index.txt
y serial
actúan como una base de datos de archivos planos para realizar un seguimiento de los certificados firmados.
# cd /root/ca/intermediate # mkdir certs crl csr newcerts private # chmod 700 private # touch index.txt # echo 1000 > serial
Creación fichero de configuración openssl.cnf
Al igual que en el apartado anterior vamos a crear un fichero de configuracion /root/ca/intermediate/openssl.cnf
# OpenSSL intermediate CA configuration file. # Copy to `/root/ca/intermediate/openssl.cnf`. [ ca ] # `man ca` default_ca = CA_default [ CA_default ] # Directory and file locations. dir = /root/ca/intermediate certs = $dir/certs crl_dir = $dir/crl new_certs_dir = $dir/newcerts database = $dir/index.txt serial = $dir/serial RANDFILE = $dir/private/.rand # The root key and root certificate. private_key = $dir/private/intermediate.key.pem certificate = $dir/certs/intermediate.cert.pem # For certificate revocation lists. crlnumber = $dir/crlnumber crl = $dir/crl/intermediate.crl.pem crl_extensions = crl_ext default_crl_days = 30 # SHA-1 is deprecated, so use SHA-2 instead. default_md = sha256 name_opt = ca_default cert_opt = ca_default default_days = 375 preserve = no policy = policy_loose [ policy_strict ] # The root CA should only sign intermediate certificates that match. # See the POLICY FORMAT section of `man ca`. 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` man page. countryName = optional stateOrProvinceName = optional localityName = optional organizationName = optional organizationalUnitName = optional commonName = supplied emailAddress = optional [ req ] # Options for the `req` tool (`man req`). default_bits = 2048 distinguished_name = req_distinguished_name string_mask = utf8only # SHA-1 is deprecated, so use SHA-2 instead. default_md = sha256 # Extension to add when the -x509 option is used. x509_extensions = v3_ca [ req_distinguished_name ] # See <https://en.wikipedia.org/wiki/Certificate_signing_request>. 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 = GB stateOrProvinceName_default = England localityName_default = 0.organizationName_default = Alice Ltd organizationalUnitName_default = 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, pathlen:0 keyUsage = critical, digitalSignature, cRLSign, keyCertSign [ usr_cert ] # Extensions for client certificates (`man x509v3_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_config`). basicConstraints = CA:FALSE nsCertType = server nsComment = "OpenSSL Generated Server Certificate" subjectKeyIdentifier = hash authorityKeyIdentifier = keyid,issuer:always keyUsage = critical, digitalSignature, keyEncipherment extendedKeyUsage = serverAuth [ crl_ext ] # Extension for CRLs (`man x509v3_config`). authorityKeyIdentifier=keyid:always [ ocsp ] # Extension for OCSP signing certificates (`man ocsp`). basicConstraints = CA:FALSE subjectKeyIdentifier = hash authorityKeyIdentifier = keyid,issuer keyUsage = critical, digitalSignature extendedKeyUsage = critical, OCSPSigning
Se han cambiado cinco opciones en comparación con el archivo de configuración de la CA raíz:
[ CA_default ] dir = /root/ca/intermediate private_key = $dir/private/intermediate.key.pem certificate = $dir/certs/intermediate.cert.pem crl = $dir/crl/intermediate.crl.pem policy = policy_loose
Crear clave privada intermedia
Cree la clave intermediate.key.pem
. Cifrar la clave intermedia con encriptación AES de 256 bits y una contraseña segura.
# cd /root/ca # openssl genrsa -aes256 \ -out intermediate/private/intermediate.key.pem 4096 Enter pass phrase for intermediate.key.pem: ******** Verifying - Enter pass phrase for intermediate.key.pem: ******* # chmod 400 intermediate/private/intermediate.key.pem
Crear certificado intermedio
Creamos el certificado intermedio igual que en el apartado anterior:
# cd /root/ca # openssl req -config intermediate/openssl.cnf -new -sha256 \ -key intermediate/private/intermediate.key.pem \ -out intermediate/csr/intermediate.csr.pem Enter pass phrase for intermediate.key.pem: secretpassword You are about to be asked to enter information that will be incorporated into your certificate request. ----- Country Name (2 letter code) [XX]:ES State or Province Name []:Sevilla Locality Name []: Organization Name []:[Nombre de tu organizacion] Organizational Unit Name []:[Nombre de tu organizacion] Common Name []:[Nombre de tu organizacion] Email Address []:[Correo electronico]
Para crear un certificado intermedio, utilice la entidad emisora raíz con la v3_intermediate_ca
para firmar la CSR intermedia. El certificado intermedio debe ser válido por un período más corto que el certificado raíz. Por ejemplo diez años sería razonable.
# cd /root/ca # openssl ca -config openssl.cnf -extensions v3_intermediate_ca \ -days 3650 -notext -md sha256 \ -in intermediate/csr/intermediate.csr.pem \ -out intermediate/certs/intermediate.cert.pem Enter pass phrase for ca.key.pem: ******** Sign the certificate? [y/n]: y # chmod 444 intermediate/certs/intermediate.cert.pem
Para estar seguro de que lo hemos realizado correctamente vamos a comprobar el certificado intermedio:
# openssl verify -CAfile certs/ca.cert.pem \ intermediate/certs/intermediate.cert.pem intermediate.cert.pem: OK
Juntar certificado raiz e intermedio
# cat intermediate/certs/intermediate.cert.pem \ certs/ca.cert.pem > intermediate/certs/ca-chain.cert.pem # chmod 444 intermediate/certs/ca-chain.cert.pem
Firmar los certificados de servidor y cliente
Firmaremos certificados utilizando nuestra CA intermedia
Solicitar certificado en el servidor web
Ya tenemos operativa nuestra entidad certificadora. Ahora desde una segunda maquina (una debian en mi caso) que hará la funciones de Servidor Web que va a solicitar un certificado, para ello vamos a crear tambien la estructura anterior:
# cd /root/ca # mkdir certs crl newcerts private # chmod 700 private # touch index.txt # echo 1000 > serial
Debemos crear un fichero de configuración /root/ca/openssl.cnf
el cual vamos a rellenar con lo siguiente:
# OpenSSL root CA configuration file. # Copy to `/root/ca/openssl.cnf`. [ ca ] # `man ca` 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/index.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 = 30 # SHA-1 is deprecated, so use SHA-2 instead. default_md = sha256 name_opt = ca_default cert_opt = ca_default default_days = 375 preserve = no policy = policy_strict [ policy_strict ] # The root CA should only sign intermediate certificates that match. # See the POLICY FORMAT section of `man ca`. 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` man page. countryName = optional stateOrProvinceName = optional localityName = optional organizationName = optional organizationalUnitName = optional commonName = supplied emailAddress = optional [ req ] # Options for the `req` tool (`man req`). default_bits = 2048 distinguished_name = req_distinguished_name string_mask = utf8only # SHA-1 is deprecated, so use SHA-2 instead. default_md = sha256 # Extension to add when the -x509 option is used. x509_extensions = v3_ca [ req_distinguished_name ] # See <https://en.wikipedia.org/wiki/Certificate_signing_request>. 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 = GB stateOrProvinceName_default = England localityName_default = 0.organizationName_default = Alice Ltd organizationalUnitName_default = 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, pathlen:0 keyUsage = critical, digitalSignature, cRLSign, keyCertSign [ usr_cert ] # Extensions for client certificates (`man x509v3_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_config`). basicConstraints = CA:FALSE nsCertType = server nsComment = "OpenSSL Generated Server Certificate" subjectKeyIdentifier = hash authorityKeyIdentifier = keyid,issuer:always keyUsage = critical, digitalSignature, keyEncipherment extendedKeyUsage = serverAuth [ crl_ext ] # Extension for CRLs (`man x509v3_config`). authorityKeyIdentifier=keyid:always [ ocsp ] # Extension for OCSP signing certificates (`man ocsp`). basicConstraints = CA:FALSE subjectKeyIdentifier = hash authorityKeyIdentifier = keyid,issuer keyUsage = critical, digitalSignature extendedKeyUsage = critical, OCSPSigning
Una vez creado dicho fichero, generamos la clave privada:
# cd /root/ca # openssl genrsa -aes256 -out private/prueba.key.pem 4096 Enter pass phrase for ca.key.pem: ********* Verifying - Enter pass phrase for ca.key.pem: ********* # chmod 400 private/ca.key.pem
Una vez tengo la clave privada, ya puedo generar la petición de certificado openssl req -new -key private/prueba.key.pem -out csr/prueba.csr.pem
:
Y lo mandamos al servidor mediante scp
.
.crs, .pem, .crt
y los datos añadido son un ejemplo pueden variar según nos nuestra preferencias.Generar certificado desde entidad con autoridad
El siguiente paso es mandar al administrador de la entidad certificadora el archivo .csr
, una vez se reciba, generaremos el certificado de la siguiente manera:
# cd /root/ca # openssl ca -config intermediate/openssl.cnf \ -extensions server_cert -days 375 -notext -md sha256 \ -in intermediate/csr/prueba.csr.pem \ -out intermediate/certs/prueba.cert.pem # chmod 444 intermediate/certs/prueba.cert.pem
.key
debe ser la clave privada de nuestro servidor para poder firmar el certificado..
Envío al servidor web y comprobar se encuentra nuestra clave privada
Ahora deberíamos enviar el certificado del servidor,el certificado intermedio y el certificado raiz, al que será nuestro servidor web y lo deberíamos copiar en /etc/ssl/certs
. Así mismo comprobamos la presencia de la clave privada del servidor, para ello volvemos a utilizar scp
y una vez en el Servidor Web lo copiamos a la carpeta /etc/ssl/certs
.
root@rebeca:~/ca# scp intermediate/certs/prueba.cert.pem intermediate/certs/intermediate.cert.pem certs/ca.cert.pem usuario@172.22.10.215:/home/usuario root@debian:/home/usuario# cp ca.cert.pem prueba.cert.pem intermediate.cert.pem /etc/ssl/certs/
Comprobamos que mi clave privada y el certificado son iguales
Para ello vamos a utilizar dos comandos uno para comprobar la clave privada openssl rsa -in /root/ca/private/prueba.key.pem -noout -modulus
y el certificado firmado openssl x509 -in prueba.cert.pem -noout -modulus
Activar modulo SSL en Apache
Luego vamos a habilitar el módulo de SSL en Apache sudo a2enmod ssl
:
Crear un virtual host para SSL
Creamos un virtual host sudo nano /etc/apache2/sites-available/default-ssl
y vamos a añadir el siguiente contenido:
<IfModule mod_ssl.c> <VirtualHost _default_:443> ServerName www.prueba.com ServerAdmin webmaster@localhost DocumentRoot /var/www <Directory /> Options FollowSymLinks AllowOverride None </Directory> <Directory /var/www/> Options -Indexes FollowSymLinks MultiViews AllowOverride None Order allow,deny allow from all </Directory> ErrorLog ${APACHE_LOG_DIR}/error.log LogLevel warn CustomLog ${APACHE_LOG_DIR}/ssl_access.log combined SSLEngine on SSLCertificateKeyFile /root/ca/private/prueba.key.pem SSLCertificateFile /etc/ssl/certs/prueba.cert.pem #SSLCACertificateFile /etc/ssl/certs/bundle.crt BrowserMatch "MSIE [2-6]" \ nokeepalive ssl-unclean-shutdown \ downgrade-1.0 force-response-1.0 # MSIE 7 and newer should be able to use keepalive BrowserMatch "MSIE [17-9]" ssl-unclean-shutdown </VirtualHost> </IfModule>
Una vez configurado el certificado en el archivo virtual host, vamos a habilitarlo sudo a2ensite default-ssl
:
Para que la configuración tenga efecto, vamos a cargarla nuevamente sudo service apache2 reload
.
Bien, ahora tienen un certificado SSL configurado y funcionando.
Si en el paso anterior hay un error, puede encontrar el porque del error en el archivo /var/log/apache2/error.log
.
Verificamos el certificado SSL desde un navegador
Una vez todo esta configurado, nos resta verificar la url desde nuestro navegador. Para esto vamos a escribir https://[Dominio]
.
La primera vez que intentemos acceder nos va a dar una alerta de que el certificado no es de confianza, esto es porque no hemos añadido o una excepcion sobre esa pagina o el certificado al navegador.
La solución es dar clic en Entiendo riesgo y luego en Anadir una excepcion con eso añadiremos esa pagina a nuestra lista de excepciones.
Debemos hacer clic en Confirmar excepcion de seguridad y ya la tendremos añadido, por lo tanto la comunicacion con tu dominio es segura (siempre y cuando la conexión se mantenga bajo https://), podrás observar el candado en verde y cerrado en la barra de navegación que lo confirma.
Y ya podemos observar que podemos acceder a la pagina de forma segura.
[…] Podemos observar como crear un certificado raiz y como firmar peticiones de certificados en el siguiente post […]