Inicio arrow Artículos arrow Seguridad arrow OpenSSL y los certificados digitales
Menú Principal
Lo más leído
Consigue Firefox
Usuarios
957 registrados
1 hoy
1 esta semana
58 este mes
Último: czar...
Formulario de acceso



... Regenerar clave
... Registro
OpenSSL y los certificados digitales Imprimir E-Mail
lunes, 05 de junio de 2006

A menudo, mientras navegamos por internet, nos encontramos frente a páginas que ofrecen la transmisión de los datos mediante un canal seguro. Habitualmente, se trata de un canal cifrado mediante el protocolo SSL. En este artículo, veremos cómo crear certificados digitales con el programa OpenSSL y veremos como instalar esos certificados en un servidor con Apache. Conseguiremos de este modo cifrar la conexión en nuestro sitio web mediante el protocolo https y podremos incluso obligar al visitante a tener instalado un certificado que le permita el acceso.


El protocolo SSL

El protocolo SSL (Secure Socket Layer) es un sistema diseñado por Netscape Communications Corporation. El protocolo pretende crear una capa de seguridad en la pila OSI, entre los niveles de TCP/IP y los protocolos de transferencia e intercambio de datos como HTTP, FTP, SMTP, etc. Su funcionamiento consiste en el cifrado de los datos intercambiados entre un servidor y un cliente mediante un algoritmo de cifrado simétrico, como RC4 o IDEA. La clave de sesión del algoritmo será cifrada a su vez mediante un algoritmo de cifrado de clave pública, habitualmente RSA. La clave de sesión se utilizará para cifrar los datos que vienen y van hacia el servidor seguro. Para cada transacción se genera una clave de sesión diferente, lo cual implica que, aun sufriendo con éxito un ataque sobre una transacción concreta, la información obtenida no servirá para futuras transacciones.

El proceso a seguir en una transacción es el siguiente:

  • El cliente solicita al sevidor una comunicación segura.
  • El servidor abre un puerto cifrado, que será gestionado por un software llamado Protocolo SSL Record. El software se sitúa por encima de TCP.
  • Finalmente, otro software llamado Protocolo SSL Handshake hará uso del Protocolo SSL Record y del puerto abierto y cifrará de forma segura la comunicación con el cliente.

Vamos a resumir a continuación los pasos que sigue el Protocolo SSL Handshake durante la negociación:

  • Hello, donde cliente y servidor negocian el conjunto de algoritmos que mantendrán la intimidad y establecerán la autentificación.
  •  Intercambio de claves, donde se produce un traspaso de información a cerca de las claves. Al final, se condigue que ambas partes utilicen la misma clave maestra.
  • Producción de clave de sesión, donde se cifran los datos intercambiados.
  • Verificación del servidor. Cuando se usa RSA como algoritmo de intercambio de claves, el cliente deberá autenticar al servidor.
  • Autenticación del cliente, fase en la cual el servidor solicita al cliente un certificado de tipo X.509, siempre que esta autenticación sea necesaria.
  •  End, donde se establece el flag para el comienzo de la transacción segura.

Instalación de OpenSSL

Instalaremos el programa OpenSSL tomando como referencia un sistema con una distribución de Fedora Core 5, aunque la instalación sobre otras distribuciones no difiere demasiado de la mostrada aquí.
En primer lugar, instalaremos, mediante la herramienta yum, los paquetes necesarios:

#yum install openssl
#yum install openssl-perl

Si no se dispone de yum, descargaremos los siguientes paquetes y los instalaremos con rpm -Uvh <paquete.rpm>

openssl-perl-0.9.8a-5.2.i386.rpm
openssl-0.9.8a-6.i386.rpm


Creación de los certificados

El primer paso para la creación de un certificado, es constatar la existencia de una Autoridad Certificadora (CA), que será la encargada de validar la autenticidad del certificado generado. Para ello, y como no es nuestra intención pagar por los servicios de ninguna, crearemos una particular que valide todos los certificados generados en nuestro servidor. Crearemos por tanto un directorio de trabajo y teclearemos los comandos siguientes en la consola (en negrita, los datos de ejmplo a introducir):

#openssl req -x509 -newkey rsa:2048 -days 1825 -keyout cakey.pem -out cacert.pem
Generating a 2048 bit RSA private key
....+++
..........+++
writing new private key to 'cakey.pem'
Enter PEM pass phrase:
Verifying - Enter PEM pass phrase:
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [GB]:SP
State or Province Name (full name) [Berkshire]:Madrid
Locality Name (eg, city) [Newbury]:Madrid
Organization Name (eg, company) [My Company Ltd]:LiberaliaTempus
Organizational Unit Name (eg, section) []:LiberaliaTempus
Common Name (eg, your name or your server's hostname) []:www.liberaliatempus.com
Email Address []: Esta dirección de correo electrónico está protegida contra los robots de spam, necesita tener Javascript activado para poder verla

Mediante esta instrucción crearemos una CA para certificados X.509 con un algoritmo de cifrado RSA de 2048 bytes. El parámetro keyout indica el fichero donde se almacenará la clave privada del CA (cakey.pem) y el parámetro out indica el fichero de almacenamiento de la clave pública (cacert.pem). Con el parámetro days indicamos la validez temporal, en días, del CA (5 años en nuestro caso).

Con la Autoridad Certificadora y las claves pública y privada creadas llega el momento de generar un certificado, siendo el primer paso la generación de una clave privada del futuro certificado. Para ello, escribiremos lo siguiente en la consola del sistema:

# openssl genrsa -des3 -out server.key -passout pass:<contraseña> 2048
Generating RSA private key, 2048 bit long modulus
......+++
.........+++
e is 65537 (0x10001)

Mediante esta instrucción la clave privada queda generada con un algoritmo de cifrado tripe DES (parámetro des3) de 2048 bytes. El parámetro out escribirá la clave en el fichero server.key, mientras que con el parámetro passout pass le indicamos la palabra de paso que cifrará la clave privada.

Antes de generar un certificado, ha de hacerse una petición del mismo. Dicha petición definirá al propietario del certificado. Mediante la orden req de Openssl realizamos dicha petición y se la enviamos a la CA creada anteriormente:

# openssl req -new -subj "/DC=liberaliatempus.com/OU=LTSys/CN=www.liberaliatempus.com" -key server.key -passin pass:<contraseña> -out server.csr

Con esta instrucción generamos una nueva (new) petición de certificado X.509. Con subj apuntaremos al propietario del certificado (CN es el nombre común o la página para la que se genera el certificado, OU es la unidad organizativa, DC es el nombre del dominio privado). Con key cargaremos la clave privada generada anteriormente. passin pass contendrá la palabra de paso que usamos para la clave privada. Para terminar, out escribirá la petición en server.csr.

Seguidamente emitiremos el certificado. Openssl lee de un fichero de configuración las características que tendrá el certificado a emitir. Podemos ver un ejemplo de uno de esos ficheros en la ruta /etc/pki/tls/openssl.cnf. Para agilizar el proceso, generaremos nuestro fichero de configuración propio tecleando lo siguiente en un fichero de texto que guardaremos como config.cnf:

basicConstraints = critical, CA:FALSE
extendedKeyUsage = serverAuth, emailProtection

Pero ¿Por qué esos parámetros y no otros? Vamos a tratar de explicarlo de forma muy resumida, pues escapan a las pretensiones de esta artículo la explicaciones a cerca de los distintos usos de un certificado. Con la extensión CA:FALSE indicamos que lo que estamos generando es un certificado que no va a actuar como CA (de usuario o de entidad). Dicha extensión será crítica (critical) y se añade para cumplir con el estándar X509v3 (teclear man x509v3_config para más información a cerca de la configuración de las extensiones).  Con extendedKeyUsage indicaremos el propósito para el cual será creado el certificado, ateniéndose a lista siguiente:

Valor            Significado
-----            -------
serverAuth       Autenticación SSL/TLS para Servidor Web.
clientAuth       Autenticación SSL/TLS para Cliente Web.
codeSigning      Firmado de código.
emailProtection  Protección de e-mail (S/MIME).
timeStamping     Trusted Timestamping
msCodeInd        Microsoft Individual Code Signing
msCodeCom        Microsoft Commercial Code Signing
msCTLSign        Microsoft Trust List Signing
msSGC            Microsoft Server Gated Crypto
msEFS            Microsoft Encrypted File System
nsSGC            Netscape Server Gated Crypto

Una vez guardado el fichero de configuración, generaremos el certificado:

# openssl x509 -CA cacert.pem -CAkey cakey.pem -req -in server.csr -days 1825 -extfile config.cnf -sha1 -CAcreateserial -out cert.pem
Signature ok
subject=/DC=liberaliatempus.com/OU=com/CN=liberaliatempus
Getting CA Private Key
Enter pass phrase for cakey.pem:

Con esta instrucción estamos creando un certificado de servidor del tipo x509 con algoritmo de cifrado SHA (-sha1) y con la misma entidad certificadora (CA) que el fichero cacert.pem creado anteriormente. Usaremos la clave privada, también generada anteriormente, contenida en el fichero cakey.pem y especificaremos, con los parámetros -req e -in, que el fichero server.csr es el que contiene las especificaciones de la petición. Finalmente validaremos el certificado durante un periodo de cinco años con el parámetro -days. Con el parámetro CAcreateserial numeraremos el certificado y con el parámetro out escribiremos el fichero de salida (en este caso, cert.pem).

Llegados a este punto, ya tenemos todo lo necesario para asegurar cualquier sitio web a través de SSL. Así, los ficheros generados mediante las diferentes instrucciones han dado como resultado lo siguiente:

cacert.pem  Clave pública (CA)
cakey.pem   Clave privada (CA)
server.key  Clave privada (Cert)
cert.pem    Certificado Servidor


Configuración de Apache

Suponiendo una versión del servidor de Apache bajo la rama 2.x, configuraremos el mismo para el soporte de SSL permitiendo, en primer lugar, que el servidor atienda peticiones sobre el puerto 443, que es el puerto estándar para https y, en segundo lugar, que cargue el módulo mod_ssl.so. Para ello atenderemos a las líneas siguientes en el fichero de configuración ssl.conf (habitualmente en /etc/httpd/conf.d/ssl.conf en un sistema con Fedora Core), que son las encargadas de configurar dicho proceso (si no existen dichas líneas, las añadiremos):

LoadModule ssl_module modules/mod_ssl.so
Listen 443

Seguidamente, crearemos el Host Virtual que se cargará por defecto en el puerto 443. El modo de añadirlo es casi idéntico al de un Host Virtual normal:

<VirtualHost _default_:443>
DocumentRoot "/usr/share/www/web-ssl"
ServerName web-ssl.server.com
ErrorLog logs/error_log
TransferLog logs/access_log
LogLevel warn
SSLEngine on
SSLCipherSuite ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP
SSLCertificateFile /etc/ssl/cert01/cert.pem
SSLCertificateKeyFile /etc/ssl/cert01/server.key
<Files ~ "\.(cgi|shtml|phtml|php3?)$">
    SSLOptions +StdEnvVars
</Files>
<Directory "/var/www/cgi-bin">
    SSLOptions +StdEnvVars
</Directory>
SetEnvIf User-Agent ".*MSIE.*" \
         nokeepalive ssl-unclean-shutdown \
         downgrade-1.0 force-response-1.0
CustomLog logs/ssl_request_log \
          "%t %h %{SSL_PROTOCOL}x %{SSL_CIPHER}x \"%r\" %b"
</VirtualHost>

Como puede observarse, los ficheros con el certificado y la clave se han guardado en la ruta /etc/ssl/cert01, aunque puede utilizarse cualquier otra ruta que nos convenga. Una vez añadido el acceso al Host y guardado el fichero de configuración, habrá que reiniciar Apache para que los cambios queden registrados. Sin embargo, al reiniciar el servidor, éste quedará parado a la espera de que se introduzca la contraseña del certificado. Esto deriva en un problema evidente si el servidor se reinicia periódicamente de forma remota por cuestiones de mantenimiento y no tenemos acceso a la consola. El servidor quedaría a la espera de forma indefinida y nunca terminaría de levantarse. Para esta situación, tenemos a nuestra disposición el parámetro SSLPassPhraseDialog de Apache, que se encargará de llamar a un programa externo que devolverá la contraseña y permitirá que el servidor siga adelante. La única condición, es que el programa devuelva la clave a través de la salida estándar stdout y tenga permisos de ejecución. Como ejemplo, podemos crear un script en bash que devuelva la clave de esta manera:

#!/bin/sh
echo password001

El cual guardaremos y al cual posteriormente daremos permisos de ejecucución mediante chmod 700 <fichero>.

Por supuesto, y como medida de seguridad, siempre será recomendable que el programa esté compilado y que sólo sea accesible al usuario root. El parámetro SSLPassPhraseDialog será añadido al fichero ssl.conf de la siguiente forma:

SSLPassPhraseDialog exec:<ruta del programa de clave>

Una vez reiniciado el servidor y con esta configuración, el acceso al ejemplo web-ssl.server.com se hará bajo un entorno de comunicación cifrada, lo cual se puede observar facilmente en cualquier navegador. Al intentar acceder por vez primera a dicha página, el navegador mostrará un error de certificado, debido a que la Entidad Certificadora no está reconocida. Esto es evitable registrando la Entidad Certificadora manualmente o bien firmando nuestros certificados a través de entidades reconocidas como CACert.org.


Certificados Cliente

Además del certificado del servidor, encargado de cifrar el contenido de cualquier comunicación entre un cliente y nuestro sitio, podemos exigir que la conexión hacia dicho sitio implique la autenticación mediante un certificado de usuario. Dicho certificado será solicitado por nuestro servidor cada vez que cualquier cliente pretenda acceder a las páginas que así lo requieran. Así conseguiremos un entorno de comunicación, si no totalmente seguro, si muy poco comprometido en todo lo referente a la seguridad de la comunicación.

Situados sobre el directorio donde generamos todos los certificados y claves anteriores, procederemos a generar la clave privada del cliente, de manera similar a cómo creamos la clave para el certificado del servidor, con la única salvedad del nombre del fichero de salida y la frase de paso de la nueva clave de cliente:

# openssl genrsa -des3 -out client.key -passout pass:<contraseña> 2048
Generating RSA private key, 2048 bit long modulus
......+++
.........+++
e is 65537 (0x10001)

A continuación, y siguiendo los mismos pasos que dimos en la generación del certificado para el servidor, realizaremos la petición del certificado:

# openssl req -new -subj "/DC=liberaliatempus.com/OU=LTSys/CN=NombreUsuario" -key client.key -passin pass:<contraseña> -out client.csr

Recordemos que el parámetro CN indica el receptor del certificado, así que aquí lo igualaremos al futuro propietario de mismo. Con la petición realizada, procederemos a crear el fichero de configuración que nos permitirá generar el certificado. En este caso, lo terminaremos guardando como config-client.cnf:

basicConstraints = critical, CA:FALSE
extendedKeyUsage = clientAuth, emailProtection

Recordemos que el parámetro clientAuth servía para la autenticación SSL/TLS para Cliente Web. El certificado se generará mediante la siguiente instrucción:

# openssl x509 -CA cacert.pem -CAkey cakey.pem -req -in client.csr -days 365 -extfile config-client.cnf -sha1 -set_serial 3 -out client03-cert.pem
Signature ok
subject=/DC=liberaliatempus.com/OU=com/CN=NombreUsuario
Getting CA Private Key
Enter pass phrase for cakey.pem:

Observaremos que en este caso se ha optado por reducir el periodo de validez del certificado a un año. Mediante el parámetro set_serial indicaremos el número de certficado a generar, que en nuestro caso es el 3. La CA se generó con el número 1 y el certificado de servidor con el 2. Es muy conveniente respetar la correlación de los números de certificado para evitar el uso del mismo número en la generación de otro certificado, lo cual acarrearía problemas con los mismos.

A los ficheros refrenciados anteriormente, habremos de sumar dos ficheros más correspondientes al nuevo certificado de cliente que se ha generado:

client.key        Clave privada (Cliente)
client03-cert.pem Certificado Cliente

Con estos dos ficheros copiados sobre la ruta referenciada por Apache (en nuestro ejemplo /etc/ssl/cert01), procederemos a modificar el VirualHost anteriormente creado para que solicite un certificado al cliente que quiera acceder al sitio. Para ello, añadiremos las líneas siguientes a la configuración del VirtualHost:

SSLCACertificateFile /etc/ssl/cert01/cacert.pem
SSLVerifyClient require

Con estos dos parámetros indicamos a Apache la ruta de la CA y le indicamos que se requiere un certificado personal de cliente para el acceso al sitio. Para el uso de SSLVerifyClient se recomienda tener instalada la rama de Apache 2.2.x, ya que ésta corrige un error de envio de datos con POST en entornos con VirtualHosts sumado al uso de SSLVerifyClient.

Tras reiniciar el servidor de Apache, el acceso a la página quedará autorizado sólo a aquellos clientes que posean un certificado emitido por nuestra entidad certificadora.


Instalando certificados

Como último paso para que toda nuestra configuración funcione de forma correcta, deberemos generar un fichero que los navegadores web reconozcan como válido y así el cliente pueda instalar adecuadamente el certificado. El formato más reconocido para este propósito es el pkcs12 y lo generaremos mediante el uso de la instrucción siguiente:

# openssl pkcs12 -export -in client03-cert.pem -inkey client.key -certfile cacert.pem -out client03-pck12.p12
Enter pass phrase for cakey.pem:
Enter Export Password:
Verifying - Enter Export Password:

La clave de exportación será solicitada al importar el certificado en el navegador. Dicho certificado quedará guardado en una ruta accesible del sitio o bien será enviado al cliente mediante correo electrónico para su posterior instalación. Aunque el proceso de instalación del certificado es distinto en cada navegador, básicamente consiste en la importación del fichero a través de la utilidad correspondiente. Por ejemplo, en el navegador Mozilla Firefox, dicha utilidad es accesible desde el menú Herramientas/Opciones/Avanzado/Ver Certificados/Importar. Un vistazo rápido a la ayuda de cada navegador nos dirigirá enseguida a la opción deseada.

Con este último paso, queda terminado el proceso de generación e instalación de certificados. Obtenemos así un entorno de seguridad bajo SSL que queda protegido mediante la emisión de distintos certificados. Dichos certificados realizarán distintas labores que irán desde proteger las comunicaciones entre cliente y servidor bajo distintos protocolos, hasta solicitar la autenticación de los clientes que quieran realizar una conexión.


Comentario[s]
ayuda!
Escrito por pchiwan el 2006-08-17 01:36:16
Ante todo quisiera felicitar al autor del artículo por su magnífico trabajo. 
 
He intentado llevar a cabo la creación del certificado digital pero justo en el último paso: 
openssl x509 -CA cacert.pem -CAkey cakey.pem -req -in server.csr -days 1825 -extfile config.cnf -sha1 -CAcreateserial -out cert.pem 
 
obtengo el siguiente error, y no tengo ni idea de cómo solucionarlo ni a qué es debido: 
5796:error:2207C082:X509 V3 routines:DO_EXT_CONF:unknown extension name:v3_conf. c:123: 
5796:error:2206B080:X509 V3 routines:X509V3_EXT_conf:error in extension:v3_conf. c:92:name=sicConstraints, value=CA:FALSE 
 
estoy prácticamente segura de que tendrá que ver con mi versión de Fedora Core (la 3)... alguna idea? Cualquiera ayuda será muy apreciada! 
Escrito por mhbeyle el 2006-08-28 15:48:52
Si te fijas en el error: 
 
name=sicConstraints, value=CA:FALSE 
 
Hay algo que no cuadra, ya que, de producirse algún error, éste debería estar referido a basicConstrains y no a sicConstrains. 
Repasa los archivos cnf a ver si están bien escritos.
Problema con el certificado para el clie
Escrito por Olatz el 2006-09-06 13:35:51
Ante todo felicitarte por el artículo, es muy bueno, claro y lo más importante: muy muy útil. 
Mi pregunta es la siguiente: el certificado cliente que he generado (siguiendo exactamente los mismos pasos que tu) no me funciona en algunos navegadores. 
En un ordenador con Fedora Core 3 utilizando los navegadores Firefox 1.0.4 y Konqueror 3.4.0-5 me ha funcionado. Sin embargo con Opera 9 no consigo cargar el certificado. 
En Windows, con internet explorer 6 y SP1 tampoco me funciona. 
 
Gracias y un saludo.
Problema con el certificado para el clie
Escrito por Olatz el 2006-09-06 13:36:04
Ante todo felicitarte por el artículo, es muy bueno, claro y lo más importante: muy muy útil. 
Mi pregunta es la siguiente: el certificado cliente que he generado (siguiendo exactamente los mismos pasos que tu) no me funciona en algunos navegadores. 
En un ordenador con Fedora Core 3 utilizando los navegadores Firefox 1.0.4 y Konqueror 3.4.0-5 me ha funcionado. Sin embargo con Opera 9 no consigo cargar el certificado. 
En Windows, con internet explorer 6 y SP1 tampoco me funciona. 
 
Gracias y un saludo.

Sólo los usuarios registrados pueden escribir comentarios.
Por favor, valídate o regístrate.

Powered by AkoComment 2.0!

 
< Anterior