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