Crear una clave privada para un server y un certificate request en un paso
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.
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, el protocolo para el cual lo usamos (podemos tener uno para HTTP, otro para SMTP y otro para IMAP), 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 PROTOCOL="HTTP" export SERIAL="00" export KEY_EXT="key" export REQ_EXT="csr"
Generación de clave privada del server y pedido de firma del certificado
Ahora vamos a crear una clave privada para nuestro server y un pedido de firma de certificado con nuestros datos asociados a dicha clave. Este pedido contiene la información que le cargamos y la clave pública asociada a dicha clave privada. La clave privada nunca sale de nuestro control (es decir, la CA nunca ve nuestra clave privada).
Automáticamente
Me aseguro de tener las variables de entorno generales seteadas y creo variables de entorno con los datos que quiero 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 la clave privada y el pedido de firma de certificado. La opción -nodes es para que no encripte la clave privada.
openssl req -utf8 -new -newkey rsa:1024 -nodes\
-keyout ${DOMAIN}_${PROTOCOL}_${SERIAL}.${KEY_EXT} -keyform PEM\
-out ${DOMAIN}_${PROTOCOL}_${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 -newkey rsa:1024 -nodes\
-keyout ${DOMAIN}_${PROTOCOL}_${SERIAL}.${KEY_EXT} -keyform PEM\
-out ${DOMAIN}_${PROTOCOL}_${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).
Generating a 1024 bit RSA private key .++++++ ...++++++ unable to write 'random state' writing new private key to 'www.example.org_HTTP_00.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]: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ó dos archivos con el mismo nombre y distinta extensión en el directorio actual.
Clave privada del server
El primer archivo es la clave privada del server con nombre ${DOMAIN}_${PROTOCOL}_${SERIAL}.${KEY_EXT}. Con los datos del ejemplo sería www.example.org_HTTP_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}_${PROTOCOL}_${SERIAL}.${KEY_EXT} /etc/ssl/private
sudo chmod -v 640 /etc/ssl/private/${DOMAIN}_${PROTOCOL}_${SERIAL}.${KEY_EXT}
sudo chown -v root:ssl-cert /etc/ssl/private/${DOMAIN}_${PROTOCOL}_${SERIAL}.${KEY_EXT}
Pedido de firma de certificado
El segundo archivo es el pedido de firma del certificado con nombre ${DOMAIN}_${PROTOCOL}_${SERIAL}.${REQ_EXT}, es decir, lo único distinto en el nombre del archivo con la clave es la extensión. Con los datos del ejemplo sería www.example.org_HTTP_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.