Cuando queremos programar o usar alguna aplicación que requiera autenticación y encriptación podemos hacer uso de certificados digitales. Para obtenerlo podemos hacer uso de un certificado obtenido mediante VeriSign, DNI electrónico o crear nosotros uno mismo.
En esta entrada de blog vamos a hacer esta última opción, que aunque no podrá ser verificado por ninguna Autoridad Certificadora (CA), nos servirá perfectamente mientras realizamos el desarrollo.
Antes de empezar, vamos a suponer que tenemos claros los conceptos del certificado digital, tales como:
También será necesario tener claro algunos conceptos muy básicos de Linux como moverse por archivos, permisos, edición, etc.
Instalar OpenSSL
Para empezar, necesitaremos OpenSSL instalado a ser posible la versión más actualizada posible, ya que si no, puede ser que alguno de los pasos no funcione correctamente.
En Windows lo descargaremos y descomprimiremos y en Linux para Ubuntu/Debian:
sudo apt-get install openssl
o para RedHat / CentOS:
yum install openssl
lo tendremos instalado.
Crear autoridad certificadora de certificados X.509
Prepararemos el entorno:
cd $HOME mkdir CA cd CA mkdir certificados mkdir privado echo '01' > contador touch certindex
Ahora generaremos el archivo de configuración OpenSSL
nano openssl.cnf
El contenido debería ser algo así:
# ----------------------- # Configuración inicial # ----------------------- dir = . # Directorio de trabajo [ ca ] default_ca = CA_default [ CA_default ] serial = $dir/contador # Contador de números de serie database = $dir/certindex # Listado de certificados new_certs_dir = $dir/certificados # Directorio para los certificados generados certificate = $dir/cacert.pem # Certificado raíz private_key = $dir/privado/cakey.pem # Clave privada del certificado raíz default_md = sha1 # Digest usado preserve = no # Preserva el orden de los campos del DN nameopt = default_ca # Muestra detalles del certificado certopt = default_ca # Muestra detalles del certificado policy = policy_match # Indica si los campos obligatorios y/o # opcionales deben ser iguales al # certificado raíz # Política de recolección de datos frente al raíz [ policy_match ] countryName = match stateOrProvinceName = match organizationName = match organizationalUnitName = optional commonName = supplied emailAddress = optional # Configuración de certificados [ req ] default_bits = 2048 # Tamaño de la clave en bits default_keyfile = key.pem # Fichero de la clave privada default_md = sha1 # Digest string_mask = nombstr # Caracteres permitidos en la clave distinguished_name = req_distinguished_name # Sección para el nombre DN req_extensions = v3_req # Sección con mas extensiones que se # añaden a la petición del # certificado # Distinguished Name. Datos públicos del certificado X.509 que identifican al propietario. [ req_distinguished_name ] 0.organizationName = Nombre de la organización 0.organizationName_default = Imaginanet organizationalUnitName = Departamento emailAddress = Correo electrónico emailAddress_max = 40 localityName = Ciudad stateOrProvinceName = Estado o provincia countryName = Código ISO del pais (dos letras) countryName_default = ES countryName_min = 2 countryName_max = 2 commonName = Nombre común (nombre del host o IP) commonName_max = 64 # Si se indica la opcion -x509 indica que se trata de un certificado CA raíz # con autoridad para firmar o revocar otros certificados [ v3_ca ] basicConstraints = CA:TRUE subjectKeyIdentifier = hash authorityKeyIdentifier = keyid:always,issuer:always [ v3_req ] basicConstraints = CA:FALSE subjectKeyIdentifier = hash
Finalmente ejecutamos
openssl req -new -x509 -extensions v3_ca -keyout privado/cakey.pem -out cacert.pem -days 3650 -config ./openssl.cnf
Creando un certificado digital X.509 en base a nuestra autoridad certificadora
openssl req -new -nodes -out imaginanet-cert.pem -config ./openssl.cnf openssl ca -out certificado-imaginanet.pem -config ./openssl.cnf -days 3650 -infiles imaginanet-cert.pem
Donde el archivo imaginanet-cert.pem corresponde a nuestra clave privada y certificado-imaginanet.pem a la pública.
Utilidades
No debemos olvidar que los certificados generados no serán validos en un entorno real de producción ya que nuestra CA no será reconocida por los navegadores o el KeyStore de Java, pero si que nos vendrá bien como entorno de desarrollo para:
- Poner un servidor web en modo seguro HTTPS
- Realizar firmas sobre ficheros o correos mediante cualquier lenguaje de programación
Añadiendo la autoridad certificadora y nuestro certificado digital a nuestro navegador: Firefox
Supongamos que hemos puesto en marcha nuestro servidor web Apache con HTTPS y el certificado digital creado. Para que el navegador nos confirme que es una página válida deberemos añadir la autoridad certificadora a la lista de autoridades certificadoras válidas. En el caso de Firefox:
Editar -> Preferencias -> Avanzado -> Cifrado -> Ver certificados -> Autoridades -> Importar
y seleccionaremos el archivo cacert.pem
Si por el contrario quisiéramos firmar digitalmente con el certificado creado, deberemos añadir el certificado digital yendo a:
Editar -> Preferencias -> Avanzado -> Cifrado -> Ver certificados -> Sus certificados -> Importar
y seleccionar la clave privada imaginanet-cert.pem e introducir la contraseña para ser guardada en el KeyStore de Firefox.
Todo documento firmado con este certificado será no válido ya que el servidor que lo firme no reconocerá a la autoridad certificadora, pero podemos añadir dicho certificado al KeyStore del lado del servidor, cosa que veremos en próximas entradas del blog.
Convertir certificados .pem / .cert (X.509) a .pfx (PKCS12)
En ocasiones es necesario el uso de certificados en formato PKCS12 de extensión PFX, como por ejemplo para la librería iText para Java / C#. Lo podemos hacer mediante el siguiente comando con OpenSSL 0.9.8k (si tenemos una versión inferior deberemos actualizar ya que no funciona en todas las aplicaciones el fichero generado):
openssl pkcs12 -inkey private_key.pem -in public_cert.cert -export -out cert.pfx
Referencias
Parte de este artículo se ha basado en http://www.linuxtotal.com.mx/ssl_apache.html
Más información:
Comentarios