Certificados Digitales
A continuación voy a describir los pasos necesarios para crear un certificado autofirmado y también cómo hacer para crear uno firmado por una autoridad certificante (CA) de confianza.

Los certificados sirven para validar quienes somos, es decir, que una tercera parte puede estar tranquilo de que está tratando con la entidad que cree y no con un atacante que la está falsificando. Además los certificados contienen la clave pública de la entidad con la que estamos tratando así que es posible crear una conexión segura (los datos viajan encriptados) a partir de una negociación previa utilizando dicha clave.
Los certificados suelen encontrarse frecuentemente al navegar por la web, cada vez que el browser accede a un sitio https un certificado es transmitido y usado para autenticar y transmitir los datos de forma segura. Si queremos montar una conexión segura entre nuestro servidor web y un usuario, necesitamos crear un certificado y configurar dicho servidor para que lo utilice.
La confianza de un certificado se logra gracias a que una Autoridad Certificante en la que confiamos (los navegadores cuentan con certificados de Autoridades Certificantes de confianza) firma nuestro certificado con su clave privada. El browser puede comprobar que un certificado fue firmado por una dada CA porque cuenta con su clave pública. Una CA de confianza sólo firmará nuestro certificado una vez que compruebe que somos quienes decimos ser.


El formato de los certificados encontrados comúnmente siguen la recomendación X.509 de la serie de recomendaciones X.500 de ITU-T, e incluye:

- Versión: el identificador del certificado.
- Algoritmo de firma: el algoritmo utilizado para firmar el certificado.
- Nombre del emisor: nombre X.500 de la CA que creó y firmó el certificado.
- Período de validez: consiste en dos fechas que indican el período de validez del certificado.
- Nombre de la entidad: nombre del usuario al que hace referencia el certificado.
- Información de la clave pública de la entidad: clave pública de la entidad junto con un identificador del algoritmo que debe usarse para esta clave.
- Identificador único del emisor (opcional): identifica unívocamente la CA que firma en el caso que el nombre X.500 se halla reusado para distintas entidades.
- Identificador único de la entidad (opcional): identifica unívocamente a la entidad en el caso que el nombre X.500 se halla reusado para distintas entidades.
- Extensiones: conjunto de uno o más campos de extensión.
- Firma: cubre todos los otros campos del certificado, ésta contiene el código hash de todos los otros campos, encriptado con la clave privada de la CA. Este campo incluye el identificador del algoritmo usado para firmar.


Entonces, qué necesitamos para crear nuestro certificado?
Antes que nada, necesitamos crear un requerimiento de certificado que enviaremos a la CA. La CA firmará nuestro requerimiento y con esto obtendremos nuestro certificado.
Ahora, las CAs de confianza cobran por este trabajo (y si, el mundo es así), por lo que tenemos dos opciones:
1) pagarle a una CA de confianza para que nos firme el certificado.
2) firmar nosotros mismos el certificado y ahorrarnos el gasto.
La solución 2 parece genial, no gastamos un peso y tenemos nuestro certificado... bueno, no es tan así. El problema es que los browsers no confían en nuestra firma (sería bastante feo que lo hicieran), por lo que los clientes verán un hermoso cartel de advertencia y deberán agregar nuestro certificado a su browser para que éste les permita seguir navegando por el sitio. Una vez que el cliente confíe en nuestro certificado, los datos viajarán encriptados de forma segura. Pues bien, el factor clave está en que el cliente confíe en nuestro certificado... piensen que como nosotros firmamos nuestro certificado, cualquier otra persona podría hacer exactamente lo mismo (decir que somos nosotros) y el cliente no podría distinguir entre quién miente y quién dice la verdad. Esta solución es perfecta si sólo necesitamos que los datos viajen encriptados.
Si necesitamos que nuestro servidor se autentique para que el cliente confíe en nosotros, deberemos pagarle a una CA.

NOTA: Para una explicación más extensa sobre los certificados X.509, pueden leer el capítulo 14.2. "X.509 Authentication Service" del libro "Cryptography and Network Security Principles and Practices - 4th edition", de William Stallings.
También está interesante el capítulo 8.5 "Management of Public Keys" del libro "Computer Networks - 4th edition", de Andrew S. Tanenbaum.


Cuánto cobran las CAs?
Depende de la CA. Hay CAs que son más confiables que otras, y por lo tanto, cobran mucho más.
Una lista reducida con algunas de las CAs que reconoce Firefox (e Internet Explorer) como confiables es:
http://www.entrust.net
http://www.geotrust.com
http://www.globalsign.com
http://www.rapidssl.com
http://www.verisign.com/
http://www.thawte.com/
http://www.godaddy.com <--- el más barato! Para saber cuáles otras reconoce firefox, pueden visitar http://www.mozilla.org/projects/security/certs/included/


Ya me leí toda la intro y tengo re claro como son los certificados (o bien no entendi un pedo pero sigo leyendo), cómo creo un certificado?

La solución que voy a mostrar es para un sistema GNU/Linux. Utilizaremos openSSL para crear los certificados y Apache como servidor web (clásica combinación linuxera). Si quieren saber cómo hacerlo en Windows, lo lamento pero nunca lo he hecho, así que tendrán que buscar ustedes mismos, el formato general será el mismo, pero las herramientas usadas pueden variar.

Los pasos a seguir son:
1) Generar una clave para el servidor útil para el algoritmo RSA, protegido con una frase de paso y de 4096 bits:
# openssl genrsa -des3 -out server.key 4096
Generating RSA private key, 4096 bit long modulus
.............++
...........................................++
e is 65537 (0x10001)
Enter pass phrase for server.key:
Verifying - Enter pass phrase for server.key:
2) Crear un pedido de firma de certificado:
# openssl req -new -key server.key -out server.csr
Enter pass phrase for server.key:
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) [AU]:AR
State or Province Name (full name) [Some-State]:Buenos Aires
Locality Name (eg, city) []:Capital Federal
Organization Name (eg, company) [Internet Widgits Pty Ltd]:itfreekzone
Organizational Unit Name (eg, section) []:
Common Name (eg, YOUR name) []:itfreekzone.blogspot.com
Email Address []:

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:mipassword
An optional company name []:
Como pueden observar, este comando nos pide una serie de datos. Algunos son opcionales (los que finalizan con []) y otros son mandatorios. Entre los datos tenemos, el código de dos letras de nuestro país, el nombre de la provincia o estado, el de la ciudad, el de la organización, el de la unidad dentro de la organización. Hay que prestar especial atención al Common Name, el nombre que pongamos acá deberá coincidir con la dirección DNS que queremos autenticar. En mi caso la dirección que quiero certificar es itfreekzone.blogspot.com. Pongan la dirección exacta, o en caso contrario el certificado no servirá. Luego podemos colocar una dirección de email, y a continuación un password y un nombre de compañía opcionales.

A partir de acá tenemos dos caminos, uno es enviar el pedido recien generado a una Autoridad Certificante para que nos firme el certificado. Si enviamos el pedido a una CA, ésta comprobará nuestra identidad (dependiendo de la CA pueden requerir más o menos datos) y luego nos devolverá el certificado firmado para que podamos utilizarlo. En este caso, saltar al paso 4. Caso contrario, pasar a 3.

3) Vamos a auto-firmar nuestro certificado con validez de 365 días. Para auto firmarnos necesitamos ejecutar el siguiente comando:
# openssl x509 -req -days 365 -in server.csr -signkey server.key -out server.crt
Signature ok
subject=/C=AR/ST=Buenos Aires/L=Capital Federal/O=itfreekzone/CN=itfreekzone.blogspot.com
Getting Private key
Enter pass phrase for server.key:
Con esto obtenemos server.crt el cual es el certificado ya firmado y listo para usar.

4) Ya tenemos nuestro certificado firmado, ya sea porque lo auto-firmamos o porque una CA nos firmó y ya nos entregó el certificado. El siguiente paso es hacer que Apache vea el certificado y lo utilice. A esta altura debemos tener lo siguiente:
server.key - la clave del servidor
server.crt - el certificado firmado
Si nuestro certificado está firmado por una CA de confianza, tal vez también necesitemos un nexo con nuestra CA para que los browsers confíen en nuestro certificado. En nexo se llama CA bundle y los CAs lo entregan junto con nuestro certificado firmado. En este caso, además de los archivos anteriores, también tendremos el ca-bundle.crt.
Por otra parte, si no queremos que cada vez que carguemos Apache éste nos pida la clave de paso de server.key, sería conveniente eliminar la encripción sobre la clave. Esto puede resultar peligroso, dado que si se roban este archivo, tendrán la clave, pero se torna muy complicado estar ingresando la clave cada vez que el server deja de funcionar. Si por ejemplo tenemos la configuración para que nuestro servidor se auto-recupere, o que alguien más pueda levantar el servidor, la página no funcionará con ssl a menos que se provea la clave. Yo elijo dejar la clave sin encripción.
Para desencriptar el archivo server.key, ejecutamos lo siguiente:
# openssl rsa -in server.key -out server.key.insecure
Enter pass phrase for server.key:
writing RSA key
Ahora, con todos estos archivos podemos configurar Apache. Primero colocaremos los archivos en un lugar seguro, no accesible a través de la web, por ejemplo en /etc/ssl/crt/, luego cambiamos los permisos para que sólo el usuario apache pueda accederlos y modificamos la configuración de Apache. Dependiendo la distribución que utilicemos el archivo de configuración de ssl puede estar en distintos lugares, por ejemplo en debian, la configuración de la página default está en /etc/apache2/sites-available/default-ssl. Igualmente podemos cambiar las configuraciones de Apache, editando el archivo /etc/apache2/apache2.conf o bien /etc/httpd/httpd.conf en distros basadas en Red Hat.
En fin, en el lugar que puedan configurar ssl, coloquen las siguientes líneas:
SSLEngine On
SSLCertificateFile /etc/apache2/ssl/server.crt
SSLCertificateKeyFile /etc/apache2/ssl/server.key.insecure
# SSLCertificateChainFile /etc/apache2/ssl/ca-bundle.crt # si tienen un certificado firmado por una CA, descomentar esta línea
Luego reiniciamos Apache:
apache2ctl restart
o bien con:
service httpd restart
si usan algún derivado de Red Hat.


Con esto terminamos con la creación del certificado y la configuración de apache. Sólo restaría la prueba de fuego. Ejecuten un browser y coloquen la dirección de su página anteponiendo https en lugar de http. Si arranca, quiere decir que vamos bien. Vean las propiedades del certificado para comprobar.


Referencias:
Los comandos que utilicé fueron extraídos de http://www.tc.umn.edu/~brams006/selfsign.html
Para saber mejor cómo funciona openSSL pueden visitar http://www.madboa.com/geek/openssl/
Una explicación extra sobre cómo crear un certificado firmado por Go Daddy está en http://www.my-whiteboard.com/ecommerce/how-to-generate-an-ssl-certificate-from-godaddy.html
Si les interesa conocer cómo es la negociación de las claves al utilizar https, pueden seguir ésta página http://www.ourshop.org/resources/ssl_step1.html


Espero que les haya resultado tan interesante como a mi. En su momento tuve que leer varias páginas para encontrar toda ésta información y perder un par de días para poder armar un servidor seguro con un certificado firmado por una CA. Mi intensión es que con este artículo puedan hacer el mismo trabajo y a su vez puedan entender la forma en que funciona. Igual siempre es interesante leer artículos extra para sacarse dudas.
La parte teórica siempre es la base para entender un mecanismo, pero hasta que no lo implementan no se chocan con realidad, osea, el cómo lo hago. Por eso es que incluí tanto teoría como un ejemplo práctico, para que puedan tener el concepto completo.

Espero comentarios y sugerencias.

6 comentarios:

MagnoBalt dijo...

uhh me vino de 10, andaba buscando algo asi, no sabia que tenias este post .Muchas Gracias muy bien explicado..

Saludos

Anónimo dijo...

Genial!

Kike Rubio dijo...

Eres un crack

Carolina Costa dijo...
Este comentario ha sido eliminado por el autor.
Carolina Costa dijo...

Oi .. eu estava muito animado para encontrar este site. Eu queria agradecer por esta leitura especial. Eu definitivamente saboreado cada pouco dele e eu tenho você bookmarked para verificar coisas novas que você postar.
Certificado e-nf

Marcos Ivan Centurion Giles dijo...

Buenísima explicación, excelente!

Publicar un comentario