Certificado autofirmado
Si el certificado se va a utilizar en un servidor lo mejor es no ponerle contraseña de acceso para evitar tener que introducirla cada vez que iniciemos el servidor. Si el certificado es para un usuario sí debemos protegerlo y crearlo cifrado con contraseña. Con la opción -nodes generamos un certificado sin contraseña. Para que durante la generación del certificado nos solicite la contraseña podemos usar la opción -des3
En primer lugar vamos a generar un fichero que contiene tanto la llave privada como el certificado público basado en ella. Observamos como podemos especificar la vigencia del certificado. El certificado no está cifrado con contraseña.
openssl req \ -x509 -nodes -days 365 \ -newkey rsa:1024 -keyout mycert.pem -out mycert.pem |
Sin embargo, si cambiamos -nodes por -des3
openssl req \
-x509 -des3 -days 365 \
-newkey rsa:1024 -keyout mycert.pem -out mycert.pem
genera un fichero de certificado con contraseña de acceso.
Como dijimos anteriormente, el fichero recién creado contiene tanto la clave pública como la privada, y esto puede comprobarse viendo el contenido del fichero.
Ahora, interesa crear tanto la llave privada como el certificado público en ficheros distintos. El resto de las opciones serían similares.
openssl req \ -x509 -newkey rsa:1024 -nodes \ -keyout cert.key -out newcert.req |
Y tendremos la llave privada en el fichero cert.key y el certificado en newcert.req.
La llave pública de una autoridad certificadora raíz tiene que ser un certificado autofirmado.
Manipulación de certificados
Automatizar la entrada de datos
Si queremos automatizar la entrada de datos, podemos evitar las molestas preguntas referentes tanto a los datos del certificado como a las contraseñas que tenemos que utilizar.
Datos del certificado
Cuando generamos un nuevo certificado podemos incluir la opción
-subj '/C=ES/ST=Malaga/L=Rincon de la V./O=IES Bezmiliana/OU=red_local/CN=CA Bezmiliana/emailAddress= |
de la que tomará todos los valores.
Otra solución para un script sería:
(echo $PAIS echo $PROVINCIA echo $CIUDAD echo $ORGANIZACION echo $UNIDAD echo $CLIENTE echo $EMAIL ) |openssl req -nodes -new -x509 -keyout cert.key -out newcert.req |
También existe la opción -batch de openssl que toma los datos del fichero de configuración para evitar que los solicite del teclado.
Gestión de contraseñas
Las opciones -passin y -passout de openssl permite varias formas de introducir las contraseñas. Con -passin podemos especificar las contraseñas para descifrar una llave privada previamente cifrada. Con -passout podemos indicar las nuevas contraseñas que asignamos a las llaves. Por ejemplo:
openssl req -new -keyout cert.key -out newcert.req -days 365 -passin pass:$PASSWORD -passout pass:$PASSWORD |
Creación de una Autoridad Certificadora
Para crear una autoridad certificadora es necesario crear una estructura de directorios, un certificado público y una llave privada. El proceso es simple, pero lo podemos simplificar aun más si instalamos openssl-perl y utilizamos el script CA.pl que encontraremos en el directorio $SSL/misc/ .
Ejecutamos:
mkdir /tmp/ssl cd /tmp/ssl /ruta/CA.pl -newca |
Ahora deberemos tener un directorio llamado demoCA que contiene un fichero llamado cacert.pem, que a su vez contiene el certificado público, el índice, el número de serie y los directorios:
-
certs un directorio para contener certificados
-
crl un directorio para contener certificados revocados
-
index.txt un fichero con el índice de certificados firmados
-
newcerts un directorio para contener los nuevos certificados emitidos
-
private un directorio que contiene el fichero cakey.pem, la llave privada
-
serial un fichero que contiene el número de serie de certificados firmados.
La clave que nos ha solicitado es la que tendremos que utilizar para abrir la llave privada cada vez que queramos firmar un nuevo certificado.
Si queremos realizar el proceso manualmente:
creamos la estructura de directorios:
mkdir demoCA mkdir demoCA/certs mkdir demoCA/crl mkdir demoCA/newcerts mkdir demoCA/private echo -n ?01? >demoCA/serial"; touch demoCA/index.txt openssl req -new -x509 \ -keyout demoCA/private/cakey.pem \ -out demoCA/cacert.pem \ -days 365 |
Es decir, para crear una autoridad certificadora basta crear la estructura de directorio, dos ficheros y una pareja de llave privada ? certificado público.
En la última orden realizamos solicitud de certificado autofirmado donde el certificado público es demoCA/cacert.pem y la llave privada es demoCA/private/cakey.pem. Como lo que pretendemos es convertirnos en una CA nuestro certificado tiene que ser autofirmado.
Confianza en una CA
OpenSSL utiliza el directorio $SSL/certs para contener los certificados de las CA en las que confía. No sólo basta copiar el fichero con el certificado en él, sino que tendremos que proporcionar a openssl una forma de localizarlo. La localización por el nombre de fichero no es adecuada ya que el nombre del fichero es completamente independiente del certificado que contiene y buscamos un nombre único para cada fichero de certificado. Un usuario no tiene el mismo concepto para un nombre de fichero que una aplicación De cada certificado podemos obtener un hash que lo puede identificar y es ese valor, el que vamos a utilizar para que OpenSSL sepa identificar el fichero que contiene el certificado. Lo más cómodo es utilizar un enlace simbólico entre el nombre de fichero que conoce el usuario y el nombre que espera encontrar OpenSSL.
Para averiguar el hash de un certificado para el enlace simbólico utilizamos:
$ openssl x509 -noout -hash -in mica.pem def616ee |
Ahora tenemos que enlazar el certificado con el nombre hash:
ln -s mica.pem def616ee.0
Los dígitos de la extensión se utilizan para evitar posibles colisiones de nombres de hash con distintos certificados, cosa que estadísticamente es posible.
Cuando una aplicación encuentra un certificado remoto, comprueba si el certificado se encuentra en cert.pem, y si no, en un fichero con nombre igual al hash del certificado. Si se encuentra la validez se considera verificada.
Algunas aplicaciones como Sendmail permiten especificar los ubicación de los certificados de confianza durante la ejecución, sin embargo otras aplicaciones no, la ubicación se decide en el momento de la ejecución.
Para reconocer y verificar certificados, tiene que poner el fichero que contiene el certificado en el directorio indicado antes y crear el enlace simbólico con el hash obtenido.
Como vimos en el ejemplo anterior sería:
ln -s mica.pem def616ee.0 |
El siguiente script se encarga de esto:
#!/bin/sh |
#http://www.madboa.com/geek/openssl/
#Paul Heinlein, heinlein(en)madboa.com # usage: certlink.sh filename [filename ...] for CERTFILE in $*; do # make sure file exists and is a valid cert test -f "$CERTFILE" || continue HASH=$(openssl x509 -noout -hash -in "$CERTFILE") test -n "$HASH" || continue # use lowest available iterator for symlink for ITER in 0 1 2 3 4 5 6 7 8 9; do test -f "${HASH}.${ITER}" && continue ln -s "$CERTFILE" "${HASH}.${ITER}" test -L "${HASH}.${ITER}" && break done done |
Formatos de certificados
Los certificados digitales se pueden almacenar en distinos formatos a cada uno de los cuales se le suele asignar una extensión al nombre del ficheros. Algunos ficheros pueden incluir simultáneamente las llasves publica y privada y también podemos mantenerlas en ficheros separados.
Llave privada
Se puede almacenar en un fichero independiente y la extensión suele ser .key o .pem. La llave privada debe mantenerse segura, mejor, protegida por contraseña. La posesión de la llave privada implica la posesión de la identidad, además partiendo de la llave privada se pueden generar la llaves públicas asociadas, más adelante se describe cómo.
Solicitud de certificado
Una soliditud de certificado es, básicamente, una llave pública asociada a una llave privada que contiene una identidad. Una solicitud de certificado, una vez firmada se convierte en un certificado.
En el caso de que no nos interese que una autoridad certificadora externa firme el certificado, una solicitud de certificado también puede ser autofirmada, convirtiéndola directamente en un certificado. Más adelante se describe como generarlas.
Las extensiones que se utilizan para los ficheros de solicitud de certificados son .req o .pem.
Certificados
Es la llave pública firmada por una autoridad. Puede tener distintos formatos, por ejemplo, los ficheros pueden ser binarios para los ficheros DER (.der), o en formato texto como los PEM (.pem). Los ficheros de texto pueden incluir una serie de textos informativos.
El formato PKCS12 es binario, contiene las laves pública y privada.
OpenSSL
Openssl es Es un conjunto de herramientas que permiten una completa gestión de certificados. Para manipular certificados tenemos la orden openssl, que admite una gran variedad de órdenes distintas, entre ellas:
-
ca Gestión de una autoridad certificadora (CA)
-
crl Gestión de revocación de certificados CLR (Certificate Revocation List)
-
crl2pkcs7 Conversiones de CRL a PKCS#7.
-
dgst Cálculo de resúmenes.
-
passwd Generación de contraseñas
-
pkcs12 Gestión de certificados PKCS#12
-
pkcs7 GEstión de certificados PKCS#7
-
req Gestión de solicitudes de certificados X.509 (Certificate Signing Request, CSR)
-
rsa Gestión de llaves RSA
Estas órdenes de openssl admiten una serie de opciones que dependen de la orden. Vamos a citar algunas de las más utilizadas:
-
-out indica el fichero de salida para la llave pública o certificado.
-
-keyout indica el fichero de salida para la llave privada. Si coincide con el fichero indicado en -out ambas llaves se guardan en el mismo fichero.
-
-in indica un fichero de entrada necesario para el proceso
-
-key indica una llave privada para utilizar en el proceso. Si la llave privada está protegida por contraseña, entonces la solicita antes de usarla.
-
-outform indica el formato de fichero de salida. Esta opción exige un argumento que es el tipo de fichero, que puede ser DER, o PEM
-
-inform se utilza para indicar el formato del fichero de entrada, DER o PEM
-
-des3 indica que la llave privada debe ir protegida con contraseña.
-
-nodes indica que la llave privada no lleva contraseña de acceso.
Configuración de OpenSSL
Una de las opciones de compilación de openssl es ?--openssldir? para indicar un directorio para los ficheros de openssl. Este directorio normalmente reúne los certificados de las CA de confianza.
La ubicación del directorio de datos de SSL depende de como se configurara en el momento de la compilación, y lo podremos encontrar en /usr/local/ssl (predefinido), /usr/share/ssl, /etc/pki/tls (Red Hat/Fedora), /etc/ssl (Gentoo), /usr/lib/ssl (Debian), /System/Library/OpenSSL (Macintosh OS X). Haremos referencia a esta directorio como $SSL.