Entidad certificadora personal con OpenSSL

Gracias a OpenSSL podemos tener comunicación encriptadas entre diferentes máquinas utilizando criptología asimetrica, es decir, claves públicas y privadas. Además, es posible montar entidades certificadoras que se encarguen de asegurar que una llave pertenece a quien dice pertenecer, de esta forma conseguimos encriptación y autentificación.

Las entidades certificadoras actuales cobrán por el servicio de firma de llaves y no suele ser precisamente asequible. Por otro lado, montar una entidad certificadora oficial también resulta muy costoso ya que se demandan unas ciertas garantias que destrás del negocio hay una cierta seguridad. Por tanto, es habitual que los administradores de pequeñas redes se creen su propios certificados para firmar sus claves. De esta forma podremos disponer de comunicaciones encriptadas sin necesidad de entidades certificadoras.

Estas entidades oficiales pagan para que aparezcan por defecto sus certificados en navegadores como Mozilla Firefox o Internet Explorer. De esta forma el propio navegador puede comprobar automáticamente que cuando se conecta a un sitio seguro, el certificado que recibe ha sido realmente firmado por una entidad oficial. Eso implica que nuestros certificados no serán reconocidos automáticamente por los navegadores a no ser que los añadamos manualmente, el único inconveniente que aporta esto es que el navegador mostrará un aviso extra al usuario (dependiendo de la configuración) advirtiendo que no reconoce la entidad certificadora.

Vamos a ver como configurar OpenSSL para montar nuestro servicio de certificación personal. Lo primero es tener OpenSSL instalado en el sistema (aptitude install openssl), la configuración la encontraremos en “/etc/ssl” y será allí donde editemos el fichero “openssl.cnf”. Os pongo un extracto del archivo con lo más importante:

...

[ ca ]
default_ca  = CA_default

[ CA_default ]
dir     = /etc/ssl/marblestationCA  # Where everything is kept
certs       = $dir/certs  # Where the issued certs are kept
crl_dir     = $dir/crl  # Where the issued crl are kept
database    = $dir/index.txt  # database index file.
new_certs_dir   = $dir/newcerts     # default place for new certs

certificate = $dir/MSca.crt     # The CA certificate
serial      = $dir/serial       # The current serial number
crl     = $dir/crl.pem      # The current CR

private_key = $dir/private/MSca.key # The private key

default_days    = 3650

...

En esta sección del fichero se define donde se va a almacenar toda la información, en mi caso lo guardaré todo en “/etc/ssl/marblestationCA”. Dentro de ese directorio creare toda una serie de subdirectorios que guardaran la información necesaria e imprescindible como por ejemplo el certificado o clave de la entidad (tanto privada como pública). También he puesto que por defecto se generen claves con un periodo de caducidad de 10 años ya que quiero olvidarme de renovar por una buena temporada.

Tendremos que crear la estructura de directorios y ficheros:

mkdir /etc/ssl/marblestationCA/
mkdir /etc/ssl/marblestationCA/certs
mkdir /etc/ssl/marblestationCA/private
mkdir /etc/ssl/marblestationCA/newcerts
mkdir /etc/ssl/marblestationCA/crl
echo "01" > /etc/ssl/marblestationCA/serial
touch /etc/ssl/marblestationCA/index.txt

A continuación crearemos la clave pública/privada de nuestra entidad certificadora:

cd /etc/ssl/marblestationCA/
openssl req -nodes -new -x509 -keyout private/MSca.key -out MSca.crt -days 3650

Es importante especificar el mismo nombre para la clave privada (MSca.key) y pública (MSca.crt) que pusimos en nuestra configuración de OpenSSL. En cuanto a las preguntas que nos haga para generar la clave:

Country Name (2 letter code) [ES]:
State or Province Name (full name) [Catalunya]:
Locality Name (eg, city) []:Tarragona
Organization Name (eg, company) [Marble Station]:
Organizational Unit Name (eg, section) []:Ejemplo
Common Name (eg, YOUR name) []:midominio.com
Email Address []:admin@midominio.com

Cabe destacar que en “Common Name” debemos poner el nombre de dominio correspondiente a la máquina donde estará la entidad certificadora.

Ahora ya tenemos nuestro servicio de certificaciones montado, las claves que hemos generado nos serviran para firmar terceras claves que serán utilizadas por ejemplo por los diferentes ordenadores de nuestra red.

Imaginemos que en el mismo servidor donde hemos montado nuestros certificados para firmar, tenemos un servidor web Apache seguro (SSL) y necesitamos un certificado firmado por nuestra entidad personal. Lo primero que tendremos que hacer será crear una petición de certificado junto a una clave privada:

openssl req -nodes -new -keyout midominio.key -out midominio.csr

Nos volverá a realizar las respectivas preguntas, debemos responder acorde para la máquina donde se va a utilizar la clave. En “midominio.key” tendremos la clave privada generada y en “midominio.csr” la petición de certificado. La entidad certificadora solo necesita acceso al segundo, vamos a generar ahora el certificado firmado por nuestra entidad personal:

openssl ca -out midominio.crt -in midominio.csr

Esto generará el archivo “midominio.crt” con el certificado firmado listo para ser usado por el solicitante. Además se guardará información referente al certificado firmado en “/etc/ssl/marblestationCA/” de forma que siempre tendremos un listado de todo lo que hemos firmado, también podremos revocar firmas (man openssl) en caso de que sea necesario.

Como comenté, ibamos a utilizarlo para nuestro servidor Apache pero también podria ser compartido por otros servicios en la misma máquina, como por ejemplo un servicio de POP3/IMAP (recomiendo dovecot) y SMTP (recomiendo exim). Es importante asegurarnos que estas aplicaciones tengan acceso de lectura al certificado y que el resto de usuarios del sistema no puedan leerlo (sobretodo la llave privada .key).

Habitualmente suelo ubicar los certificados de servicios en /etc/ssl/certs y /etc/ssl/private de la máquina que los vaya a usar:

mv midominio.crt /etc/ssl/certs
mv midominio.key /etc/ssl/private

La petición de certificado midominio.csr no lo vamos a necesitar más puesto que ya hemos generado el certificado.

Ahora podriamos seguir generando nuevos certificados para después firmarlos y repartirlos entre las máquinas de nuestra red que dispongan de servicios con conexión segura.

En resumen, hemos llevado a cabo dos acciones:

  1. Generación de los certificados de nuestra entidad certificadora no oficial (clave pública “MSca.crt” y clave privada “MSca.key”), se guardará toda la información en “/etc/ssl/marblestationCA/”
  2. Generación de certificados firmados para los servicios o máquinas de nuestra red, se guardará automáticamente la información necesaria en “/etc/ssl/marblestationCA/” y la clave pública/certificado firmado se guardarán en la máquina que los vaya a usar (“/etc/ssl/certs”, “/etc/ssl/private” respectivamente):
    1. Generación de una clave privada (midominio.key) con peticion de certificado (midominio.csr).
    2. Firma de la petición con nuestro certificado de entidad.
    3. El solicitante recibirá su certificado firmado (midominio.crt) que usará en conjunto con su clave privada para su servicio (podremos eliminar la petición midominio.csr).

Autor: marble

This entry was posted in Seguretat. Bookmark the permalink.

4 Responses to Entidad certificadora personal con OpenSSL

  1. Anonymous says:

    Hola. He seguido los pasos para crear una entidad certificadora y un certificado firmado por la CA, pero tengo un problemilla. Al firmar la petición con la ca, se me EXIGE que tanto la petición como la CA tengan exactamente el mismo Organization Name, pero eso no tiene mucho sentido. ¿Sabéis por qué puede ser?
    Gracias

  2. Anonymous says:

    hay que ir al fichero openssl.cnf, que esta en el directorio /etc/ssl (en gentoo) y buscar una seccion llama policy, y cambiar lo que corresponda (match,optional y suplied son los valores permitidos…)

  3. Anonymous says:

    Hola a todos como puedo aplicar un certificado con windows?

  4. wwah!!
    q
    buena
    pag…
    ze entendii
    to0do0
    eaea!!!
    paze
    mii exXtrao0rdiinariio0
    jeje
    (ª_ª)
    (º_º)
    (~_~)
    (((XD)))!!!

Leave a Reply