Un certificado autofirmado puede ser útil para implementar SSL en entornos de desarrollo/testeo, o para el caso en que no se cuente con presupuesto suficiente para comprar uno firmado por una autoridad certificante de confianza (aunque algunas autoridades certificantes como namecheap ofrecen certificados económicos). Un certificado autofirmado no sirve para garantizar la identidad de un servidor, pero al menos provee un canal de comunicación seguro. Generar un certificado autofirmado también sirve para entender el proceso de creación y firma de un certificado y sus diferentes componentes.



Antes de comenzar, crear un directorio donde guardar certificados y sus claves:

mkdir certs
cd certs/
Primer paso

Primero se debe generar una solicitud de firma de certificado (CSR, Certificate Signing Request). Esta contiene la información del certificado junto con la clave pública, y es lo que envía a las autoridades certificantes para ser firmada (generar el certificado de confianza). El archivo CSR utiliza generalmente el formato binario PKCS #10.

Con el siguiente comando, se genera una clave privada y una solicitud de firma de certificado con su correspondiente clave pública:

openssl req -new -nodes -keyout linuxito.key -out linuxito.csr -days 3650

Este comando solicita al usuario ingresar por entrada estándar cada uno de los campos del certificado, siendo el más importante el common name (CN), el cual debe coincidir con el nombre de host calificado del servidor (por ejemplo "www.linuxito.com") si se va a utilizar para proveer SSL en un servidor Web (HTTPS).

El parámetro -keyout especifica el nombre de archivo para la clave privada, mientras que -nodes indica que no se proteja con contraseña. Esto se hace por conveniencia ya que, de lo contrario, cada vez que se reinicie el servicio (que utilice dicho certificado) será necesario ingresar la contraseña (passphrase) para desencriptar la clave privada (lo cual entorpece la administración).

Por otro lado, el parámetro -out indica el nombre de archivo para el CSR y -days indica la duración de la validez del CSR. No confundir -days con el período de validez del certificado una vez emitido. Este número sólo indica la cantidad de días que tiene la autoridad certificante para firmar la solicitud (luego del cual será necesario generar una nueva solicitud).

Al finalizar la ejecución se han generado dos archivos:

root@linuxito:~/certs# ll
total 8.0K
-rw-r--r-- 1 root root 1.1K Oct  1 11:15 linuxito.csr
-rw-r--r-- 1 root root 1.7K Oct  1 11:15 linuxito.key

Por supuesto, al no proteger la clave privada con contraseña, será necesario ajustar sus permisos de lectura adecuadamente:

chmod 400 linuxito.keyout

De esta forma se mantiene a la clave privada en secreto:

root@linuxito:~/certs# ll
total 12K
-rw-r--r-- 1 root root 1.4K Oct  1 11:15 linuxito.crt
-rw-r--r-- 1 root root 1.1K Oct  1 11:15 linuxito.csr
-r-------- 1 root root 1.7K Oct  1 11:15 linuxito.key

El formato de archivo PKCS #10 se codifica en Base64:

root@linuxito:~/certs# cat linuxito.csr 
-----BEGIN CERTIFICATE REQUEST-----
MIIC7jCCAdYCAQAwgagxCzAJBgNVBAYTAkFSMRUwEwYDVQQIDAxCdWVub3MgQWly
ZXMxGDAWBgNVBAcMD0JhaMODwq1hIEJsYW5jYTERMA8GA1UECgwITGludXhpdG8x
ETAPBgNVBAsMCFNpc3RlbWFzMRkwFwYDVQQDDBB3d3cubGludXhpdG8uY29tMScw
JQYJKoZIhvcNAQkBFhhsaW51eGl0b0BvcGVubWFpbGJveC5jb20wggEiMA0GCSqG
SIb3DQEBAQUAA4IBDwAwggEKAoIBAQC4l2EqXl9tu06QksmEupdPUc3mQaJhBaT0
id3FQlOUsR640DPzrDf24ikxhJ/IdtbQ7jH23O0tiXpqipZudkDM73fl4PUhiR2J
CZarAG/1NFMItTgGqEaf+CepyDOWS5lHozun4/D16zM72H/wSR8LxF2sqDp+j8H+
n4FGPdGJ4lvCSIM2WTOzUqUAXFZNs/F7bsL81/1C3t485yXEso1nbz3eW7uFx/jq
bNhjznkSIN72byx6jYPG4mS5C/ptgCGHzf+rAFdGbzWNQpnFvC/8OkLrN2piuqXy
3uxGjA4yT1cdZZmRYHF2QdCdg465pJTTrTQn8jbtiGx/QPf7xet5AgMBAAGgADAN
BgkqhkiG9w0BAQUFAAOCAQEAS9Qj7nIFoW79+4Ag1wlOFKHjNT/Chf4iyYMpLe3P
sCHnWAAEC3LDaX3eis5MsqqyoKGC9C0WM2tSizc8RBrmQ4GWU2SvRS7c+SOly/+/
nnbUYlxRsiScsEhm30Y3jhirxeCSZHUIxip2Ek8inoI8X72PnYCVAYkw6kPKM313
yazyoQQlP640sLfA8TImGDcf/AqZalvArA2PAqfHNQMjPdrjWSz94dOJFaXy0hy+
WngY7N+XehPbJ6Ddis/8rJ0TaeNugcprc1bmyTpoObVhE9qP4Qbn1Mb+L37yN8EB
+Wz+7eYSf+pfUbYFnEbGmohAokjEaB3MB9Kgt0xUsF6uKA==
-----END CERTIFICATE REQUEST-----

Es posible decodificarlo utilizando el comando base64, aunque es un formato es binario:

grep -v "^--" linuxito.csr | base64 -d | tr -dc '[:print:]'

Por ejemplo:

root@linuxito:~/certs# grep -v "^--" linuxito.csr | base64 -d | tr -dc '[:print:]'
00010UAR10UBuenos Aires10UBaha Blanca10ULinuxito10USistemas10Uwww.linuxito.com1'0%*Hlinuxito*openmailbox****0"0*H0a*^_mNOQAaBS37)1v1-zjnv@w!o4S8F'3KG;3;I]:~F=[H6Y3R\VM{nB<%go=[lcy o,zdm!WFo5B/:B7jbF2OWe`qvA4'6l@y0*HK#rn N5?")-!Xri}L-3kR7<DCSdE.#vb\Q$HfF7du*vO"<_0C3}w%?42&7j[5#=Y,Zxz'inksV:h9a/~7l_QF@HhLT^(root@linuxito:~/certs# 

Para interpretarlo correctamente es mejor utilizar el siguiente comando:

openssl req -subject -noout -in linuxito.csr

Por ejemplo:

root@linuxito:~/certs# openssl req -subject -noout -in linuxito.csr
subject=/C=AR/ST=Buenos Aires/L=Bah\xC3\x83\xC2\xADa Blanca/O=Linuxito/OU=Sistemas/CN=www.linuxito.com/emailAddress=linuxito*openmailbox****

También es posible volcar toda la información del certificado (no sólo el subject) en formato de texto plano con el siguiente comando:

openssl req -text -noout -in linuxito.csr

Por ejemplo:

root@linuxito:~/certs# openssl req -text -noout -in linuxito.csr
Certificate Request:
    Data:
        Version: 0 (0x0)
        Subject: C=AR, ST=Buenos Aires, L=Bah\xC3\x83\xC2\xADa Blanca, O=Linuxito, OU=Sistemas, CN=www.linuxito.com/emailAddress=linuxito*openmailbox****
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                Public-Key: (2048 bit)
                Modulus:
                    00:b8:97:61:2a:5e:5f:6d:bb:4e:90:92:c9:84:ba:
                    97:4f:51:cd:e6:41:a2:61:05:a4:f4:89:dd:c5:42:
                    53:94:b1:1e:b8:d0:33:f3:ac:37:f6:e2:29:31:84:
                    9f:c8:76:d6:d0:ee:31:f6:dc:ed:2d:89:7a:6a:8a:
                    96:6e:76:40:cc:ef:77:e5:e0:f5:21:89:1d:89:09:
                    96:ab:00:6f:f5:34:53:08:b5:38:06:a8:46:9f:f8:
                    27:a9:c8:33:96:4b:99:47:a3:3b:a7:e3:f0:f5:eb:
                    33:3b:d8:7f:f0:49:1f:0b:c4:5d:ac:a8:3a:7e:8f:
                    c1:fe:9f:81:46:3d:d1:89:e2:5b:c2:48:83:36:59:
                    33:b3:52:a5:00:5c:56:4d:b3:f1:7b:6e:c2:fc:d7:
                    fd:42:de:de:3c:e7:25:c4:b2:8d:67:6f:3d:de:5b:
                    bb:85:c7:f8:ea:6c:d8:63:ce:79:12:20:de:f6:6f:
                    2c:7a:8d:83:c6:e2:64:b9:0b:fa:6d:80:21:87:cd:
                    ff:ab:00:57:46:6f:35:8d:42:99:c5:bc:2f:fc:3a:
                    42:eb:37:6a:62:ba:a5:f2:de:ec:46:8c:0e:32:4f:
                    57:1d:65:99:91:60:71:76:41:d0:9d:83:8e:b9:a4:
                    94:d3:ad:34:27:f2:36:ed:88:6c:7f:40:f7:fb:c5:
                    eb:79
                Exponent: 65537 (0x10001)
        Attributes:
            a0:00
    Signature Algorithm: sha1WithRSAEncryption
         4b:d4:23:ee:72:05:a1:6e:fd:fb:80:20:d7:09:4e:14:a1:e3:
         35:3f:c2:85:fe:22:c9:83:29:2d:ed:cf:b0:21:e7:58:00:04:
         0b:72:c3:69:7d:de:8a:ce:4c:b2:aa:b2:a0:a1:82:f4:2d:16:
         33:6b:52:8b:37:3c:44:1a:e6:43:81:96:53:64:af:45:2e:dc:
         f9:23:a5:cb:ff:bf:9e:76:d4:62:5c:51:b2:24:9c:b0:48:66:
         df:46:37:8e:18:ab:c5:e0:92:64:75:08:c6:2a:76:12:4f:22:
         9e:82:3c:5f:bd:8f:9d:80:95:01:89:30:ea:43:ca:33:7d:77:
         c9:ac:f2:a1:04:25:3f:ae:34:b0:b7:c0:f1:32:26:18:37:1f:
         fc:0a:99:6a:5b:c0:ac:0d:8f:02:a7:c7:35:03:23:3d:da:e3:
         59:2c:fd:e1:d3:89:15:a5:f2:d2:1c:be:5a:78:18:ec:df:97:
         7a:13:db:27:a0:dd:8a:cf:fc:ac:9d:13:69:e3:6e:81:ca:6b:
         73:56:e6:c9:3a:68:39:b5:61:13:da:8f:e1:06:e7:d4:c6:fe:
         2f:7e:f2:37:c1:01:f9:6c:fe:ed:e6:12:7f:ea:5f:51:b6:05:
         9c:46:c6:9a:88:40:a2:48:c4:68:1d:cc:07:d2:a0:b7:4c:54:
         b0:5e:ae:28

Con eso verificamos que la solicitud sea correcta.

Segundo paso

A continuación es posible enviar el CSR a una autoridad certificante para que lo firme y emita el certificado correspondiente. Sin embargo es posible también firmar la solicitud con su misma clave privada, generando así un certificado "autofirmado". Para ello ejecutar:

openssl x509 -req -days 3650 -in linuxito.csr -signkey linuxito.key -out linuxito.crt

El subcomando x509 se utiliza para firmar solicitudes y verificar certificados. La opción -req indica que se intenta crear un certificado a partir de una solicitud desde el archivo especificado por -in. El certificado será guardado con el nombre que indica -out y será válido por -days días a partir de la fecha actual del servidor. Por último, el parámetro -signkey indica la clave con la que será firmado el certificado, la cual (en este ejemplo) es la propia clave privada del certificado emitido.

Con este comando se genera el certificado autofirmado linuxito.crt:

root@linuxito:~/certs# ll
total 12K
-rw-r--r-- 1 root root 1.4K Oct  1 11:15 linuxito.crt
-rw-r--r-- 1 root root 1.1K Oct  1 11:15 linuxito.csr
-r-------- 1 root root 1.7K Oct  1 11:15 linuxito.key

Es posible verificar su validez mediante:

root@linuxito:~/certs# openssl x509 -subject -issuer -enddate -noout -in linuxito.crt
subject= /C=AR/ST=Buenos Aires/L=Bah\xC3\x83\xC2\xADa Blanca/O=Linuxito/OU=Sistemas/CN=www.linuxito.com/emailAddress=linuxito*openmailbox****
issuer= /C=AR/ST=Buenos Aires/L=Bah\xC3\x83\xC2\xADa Blanca/O=Linuxito/OU=Sistemas/CN=www.linuxito.com/emailAddress=linuxito*openmailbox****
notAfter=Sep 28 15:15:34 2025 GMT

Queda claro que el certificado es autofirmado al notar que el subject ("asunto" o "sujeto" del certificado) coincide con el issuer (emisor del certificado, quien lo firma). El certificado expira el 28 de septiembre de 2025 pues se ha utilizado la cantidad de días 3650 al momento de firmarlo.

Ya tenemos listo nuestro certificado autofirmado en dos simples pasos.

El certificado se emite en el formato binario DER (Distinguished Encoding Rules), codificado también en Base64:

root@linuxito:~/certs# cat linuxito.crt
-----BEGIN CERTIFICATE-----
MIIDzjCCArYCCQCIkWJuDyz+qjANBgkqhkiG9w0BAQUFADCBqDELMAkGA1UEBhMC
QVIxFTATBgNVBAgMDEJ1ZW5vcyBBaXJlczEYMBYGA1UEBwwPQmFow4PCrWEgQmxh
bmNhMREwDwYDVQQKDAhMaW51eGl0bzERMA8GA1UECwwIU2lzdGVtYXMxGTAXBgNV
BAMMEHd3dy5saW51eGl0by5jb20xJzAlBgkqhkiG9w0BCQEWGGxpbnV4aXRvQG9w
ZW5tYWlsYm94LmNvbTAeFw0xNTEwMDExNTE1MzRaFw0yNTA5MjgxNTE1MzRaMIGo
MQswCQYDVQQGEwJBUjEVMBMGA1UECAwMQnVlbm9zIEFpcmVzMRgwFgYDVQQHDA9C
YWjDg8KtYSBCbGFuY2ExETAPBgNVBAoMCExpbnV4aXRvMREwDwYDVQQLDAhTaXN0
ZW1hczEZMBcGA1UEAwwQd3d3LmxpbnV4aXRvLmNvbTEnMCUGCSqGSIb3DQEJARYY
bGludXhpdG9Ab3Blbm1haWxib3guY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A
MIIBCgKCAQEAuJdhKl5fbbtOkJLJhLqXT1HN5kGiYQWk9IndxUJTlLEeuNAz86w3
9uIpMYSfyHbW0O4x9tztLYl6aoqWbnZAzO935eD1IYkdiQmWqwBv9TRTCLU4BqhG
n/gnqcgzlkuZR6M7p+Pw9eszO9h/8EkfC8RdrKg6fo/B/p+BRj3RieJbwkiDNlkz
s1KlAFxWTbPxe27C/Nf9Qt7ePOclxLKNZ2893lu7hcf46mzYY855EiDe9m8seo2D
xuJkuQv6bYAhh83/qwBXRm81jUKZxbwv/DpC6zdqYrql8t7sRowOMk9XHWWZkWBx
dkHQnYOOuaSU0600J/I27Yhsf0D3+8XreQIDAQABMA0GCSqGSIb3DQEBBQUAA4IB
AQBZxp1RPFKmizVxmg99Hev1FpaH5SzDq7IYsvZAtRK/2zSKGZ2qdZ1i18xTSbz2
m51b+Epp0Ws+OPLyUG7Zh4FzPnstnQr9W3WeeiedDrksZfrW78pjgaeAZHBKxeH+
eJoeQ9BalgS4n1EFJPZYfWDI/U2fcw+5GIUndUQB1oBVhYBZQohdGXHf2YYo3sH0
GRmxGYhUchQzCuFbiNWJkDk3OVYowil4iR5pNM8NGFwQtv+NGGFiOvTG51hQjB2r
RBfwRrExxXMtEHcglx/gLbdz7H2uffsX14S6jr185EWG6lnjKdwY4gP4t72o1crc
Ja3iVO4NrkbxCjtpYQEOFags
-----END CERTIFICATE-----

Al igual que el CSR, es posible decodificarlo con base64.

Cómo instalar un certificado SSL en Nginx

Para instalar un certificado SSL en un servidor Web Nginx se debe crear en la configuración una nueva sección servidor dentro del protocolo "http" que incluya los siguientes parámetros:

    server {
        listen 443 ssl;

        ssl_certificate      linuxito.crt;
        ssl_certificate_key  linuxito.key;

        ssl_session_cache    shared:SSL:1m;
        ssl_session_timeout  5m;

        ssl_ciphers  HIGH:!aNULL:!MD5;
        ssl_prefer_server_ciphers  on;

        //...

    }

Luego copiar el certificado y su clave privada al directorio de configuración de Nginx:

cp linuxito.crt linuxito.key /usr/local/nginx/conf/

Por último, se debe otorgar permiso de lectura (tanto al certificado como a la clave privada) para el usuario con el que corre Nginx.

Más información

man openssl
man req
man x509

Referencias

X.509

Certificate signing request

Base64


Tal vez pueda interesarte


Compartí este artículo