Crear una clave privada para un server y un certificate request en dos pasos
Esta es una tarea del comprador del certificado... el usuario que haga esto no debe ser el que esté configurado como Autoridad de Certificación (es decir, no debe tener seteada la variable ${OPENSSL_CONF} apuntando al openssl.conf de la CA.
La ventaja de hacer esto en dos pasos es que podemos generar la clave sin passphrase de modo tal de no tener que acceder a la consola cada vez que se reinicia el server (ojo que hay que cuidar mucho la clave privada, ya que no está encriptada).
Tabla de Contenidos
Entorno y nombres de archivos para claves y certificados
Vamos a usar algunas variables de entorno para que los comandos nos sirvan en muchos casos. El nombre de los archivos va a tener el nombre del dominio y un número de serie nuestro (para poder mantenerlo a medida que se van venciendo los certificados viejos y usando nuevos).
Supongamos que queremos generar la primera clave y certificado para el servidor web del dominio www.example.org, entonces creamos las variables de entorno:
# Si queremos un certificado para todos los subdominios de un dominio, # acá pondríamos un NOMBRE LÓGICO para esto (ya que esto va a generar # nombres de archivo): # export DOMAIN="WILDCARD.example.org" export DOMAIN="www.example.org" export SERIAL="00" export KEY_EXT="key" export REQ_EXT="csr" export KEY_LENGTH="2048"
Generación de clave privada del server
Me aseguro de tener las variables de entorno seteadas y uso el siguiente comando para crear la clave privada:
# primero creo la clave privada
openssl genrsa -out ${DOMAIN}_${SERIAL}.${KEY_EXT} ${KEY_LENGTH}Esto genera la clave privada sin pedir la passphrase:
Generating RSA private key, 2048 bit long modulus ....................................+++ .....................................................................................................+++ unable to write 'random state' e is 65537 (0x10001)
esto generó en el directorio actual un archivo ${DOMAIN}_${SERIAL}.${KEY_EXT}. Con los datos del ejemplo sería www.example.org_00.key.
Este archivo es importante y
SECRETO
. Nadie lo debe poder ver ya que quien lo vea podrá impersonar nuestro server.
En el server normalmente se guarda en /etc/ssl/private, con dueño:grupo root:ssl-cert y permisos 640 (-rw-r-----). Si ya estamos en el servidor, esto podemos hacerlo así:
sudo cp -v ${DOMAIN}_${SERIAL}.${KEY_EXT} /etc/ssl/private
sudo chmod -v 640 /etc/ssl/private/${DOMAIN}_${SERIAL}.${KEY_EXT}
sudo chown -v root:ssl-cert /etc/ssl/private/${DOMAIN}_${SERIAL}.${KEY_EXT}
Generación del pedido de firma de certificado
Ahora vamos a crear un pedido de firma de certificado con nuestros datos asociados a la clave. Este pedido contiene la información que le cargamos y la clave pública asociada a nuestra clave privada. La clave privada nunca sale de nuestro control (es decir, la CA nunca ve nuestra clave privada).
Automáticamente
Creamos variables de entorno con los datos que queremos que aparezcan en el certificado:
export COUNTRY="AR" # Si queremos un certificado para todos los subdominios de un dominio, # acá pondríamos el WILDCARD '*' para esto (ya que esto va a generar # el pedido de certificado en sí): # export DOMAINNAME=*.example.org # si $DOMAIN era un dominio, común y corriente, acá va exactamente lo mismo export DOMAINNAME=$DOMAIN export STATE="Mi Provincia" export LOCALITY="Mi Ciudad" export ORGANIZATION="El Nombre de mi Organización o Empresa" export ORG_UNIT="Si quiero pongo el nombre de una subdivisión dentro de mi organización" export EMAIL="webmaster@example.org"
Ahora corro el comando para generar el pedido de firma de certificado
openssl req -utf8 -new -key ${DOMAIN}_${SERIAL}.${KEY_EXT} -keyform PEM\
-out ${DOMAIN}_${SERIAL}.${REQ_EXT} -outform PEM\
-subj "/C=${COUNTRY}/ST=${STATE}/L=${LOCALITY}/O=${ORGANIZATION}/OU=${ORG_UNIT}/CN=$DOMAINNAME/emailAddress=$EMAIL/"
Interactivamente
Si preferimos cargar los datos para el pedido de certificado en forma interactiva, entonces hacemos:
openssl req -utf8 -new -key ${DOMAIN}_${SERIAL}.${KEY_EXT} -keyform PEM\
-out ${DOMAIN}_${SERIAL}.${REQ_EXT} -outform PEMEsto va a arrancar el pedido de requerimiento en modo interactivo (pongo las respuestas en mayúsculas). Es obligatorio llenar:
- Country Name: el código de 2 letras del país
- Organization Name: el nombre de la empresa u organización
Common Name:
OJO
acá va el nombre de dominio que va a usar el server. No es lo mismo www.example.org que example.org, pero se puede usar *.example.org (no todas las CA aceptan wildcard certificates, pero si lo firmamos nosotros mismos, no hay problemas).
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]:Ciudad Autónoma de Buenos Aires Locality Name (eg, city) []: Organization Name (eg, company) [Internet Widgits Pty Ltd]:NOMBRE DE MI ORGANIZACIÓN Organizational Unit Name (eg, section) []:NOMBRE DEL ÁREA (SI QUIERO) Common Name (eg, YOUR name) []:WWW.EXAMPLE.ORG Email Address []:WEBMASTER@EXAMPLE.ORG Please enter the following 'extra' attributes to be sent with your certificate request A challenge password []: An optional company name []:
Salida
Cualquiera de los comandos openssl req de arriba (automático o interactivo), generó un archivo con el mismo nombre que nuestro archivo de clave, pero con extensión .csr (certificate signing request) que es lo que se le debe enviar a la CA para que lo firme, generando así un certificado.
Esto generó en el directorio actual un archivo ${DOMAIN}_${SERIAL}.${REQ_EXT}, es decir, lo único distinto es la extensión. Con los datos del ejemplo sería www.example.org_00.csr (.csr == certificate signing request).
Este archivo es lo que hay que mandar a la Certification Authority para que genere un certificado y nos lo mande.