Fundamentos TLS
Un certificado se utiliza para garantizar la confianza entre dos partes durante una transacción.
Cuando un usuario intenta acceder a un servidor web, los certificados TLS garantizan que la comunicación entre el usuario y el servidor esté cifrada y que el servidor y el usuario sean quienes dicen ser.
Si un usuario enviara sus credenciales sin cifrado, un hacker con un simple sniffer podría recuperar las credenciales rastreando el tráfico de la red e invadir la cuenta del usuario.
Una vez cifrados los datos, serán desordenados y solo quien tenga la clave podrá descifrarlos; si alguien rastrea la red, esos datos no tendrán ningún sentido.
Si la clave para descifrar necesita ser enviada al servidor por la misma red entonces no tendría sentido, pues esa clave también podría ser interceptada en el camino y sería usada para descifrar los datos.
El sistema en que ambos lados conocen la clave de descifrado se llama criptografía simétrica. La misma clave usada para cifrar se usa para descifrar.
La criptografía asimétrica es cuando un par de claves, una clave PÚBLICA que cifra los datos (conocida por todos) y otra clave PRIVADA (conocida solo por el destinatario) que descifrará los datos. Cuando queremos enviar algo a alguien debemos cifrar el contenido con su clave PÚBLICA y solo el destinatario podrá descifrar usando su clave PRIVADA.
Ya hacemos todo este proceso en GitHub, GitLab, SSH, etc.
Si no tienes un par de claves para SSH, es hora de tener uno.
ssh-keygen
El comando anterior generará un par de claves para propósito de ssh.
- id_rsa: es la clave privada que solo tú debes conocer
- id_rsa.pub: es tu clave pública que puedes colocar en Github, GitLab, en los servidores a los que accedes vía ssh, etc.
Sabiendo este escenario, cuando accedemos a un servidor vía https en el navegador por ejemplo, el servidor envía automáticamente la clave pública de él para el navegador del usuario. El navegador crea una clave de criptografía simétrica (él ya la está conociendo) la cifra con la clave pública del servidor y la envía de vuelta para él. Solo el servidor es capaz de descifrarla con su clave privada. Luego, ambos conocerán una clave simétrica sin que nadie más la conozca y a partir de ese momento es posible cifrar todo usando solo la clave simétrica.
Es crucial entender el funcionamiento del par de claves asimétricas: al cifrar algo con la clave pública, solo la clave privada correspondiente puede descifrarlo. No es posible descifrar algo cifrado con la misma clave pública. Por otro lado, si algo es cifrado con tu clave privada, puede ser descifrado con tu clave pública, que es conocida públicamente. Por lo tanto, es fundamental cifrar todo destinado a ti con tu clave pública, mientras que lo destinado a otros debe ser cifrado con sus respectivas claves públicas.
Para generar un par de claves de propósito SSL, el comando es un poco diferente.
openssl genrsa -out mysite.key 1024
cat mysite.key
-----BEGIN PRIVATE KEY-----
MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAM7KqoAHnpP91ix8
O33/HIKxAmm1vIludtZ0YdWoEBlLZ2DMmq7e8MbP6QEkPuElu6g9eZLqb0zVNDsP
UETlYe2nJ+oLJWH0M6WIwIgoITzyIJRjwK9QVTW7AqAOePtlugeEE/JyrlZGzuog
M2xMHUr4JIx19DsUNoXhpt++2mTlAgMBAAECgYAYvOXoqwCtc5BLghEb4YjnmYVQ
YA1N44kT3phVluVWIU8cpV1bzg+/uN+G428iQAFS/wesK59k8Zxt9EcF9urf7C5c
gnS4RTD7FpYyTn8sGPe5CvAort89kFSeYEoAzfPaIjpxGWg5mBMz2OBU+gPLC+3e
8RZT80WIQvR9MuGrgQJBAOvIcMf/bCH/0mdhGtXlP/lFXF+WEMK7jsb+DWbTYAXu
sYwan3/TfsZPvMEqQHLeWmDXvA+rpATT8NaIOuaj9uMCQQDghdnjf/5hDSeFHlpc
HNFX0ToE6THqVl9kRevVWUsuAnOMuPRCfC43+yF7olGmSC26A1D0vXRD18GyaNOf
0zeXAkEAilikBFXU5uYqWMpbaqIHNYYDO3rb/sb6cbxjtK/WKeTyfJiqeeBpBIeI
43adNklNkoFDMZauuL57FAX/OZF/rQJAV81geSxLsW5wfwlwssb+QwZqVxNO1uJy
KYeCg4uI7/Q7ddO6iemANZo67Nt8bLebUjwLw7n3JrTQZdHCuKTj/wJBAMW+rymx
DrgwtfuIZwRCWIH7xSQmLNa/DWkFc+zMtbBiMIFFXRVKm8/zJyQOVY1PCqcd50vc
FrcqB+7CxSbRlYQ=
-----END PRIVATE KEY-----
openssl rsa -in mysite.key -pubout > mysite.pem
cat mysite.pem
-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDOyqqAB56T/dYsfDt9/xyCsQJp
tbyJbnbWdGHVqBAZS2dgzJqu3vDGz+kBJD7hJbuoPXmS6m9M1TQ7D1BE5WHtpyfq
CyVh9DOliMCIKCE88iCUY8CvUFU1uwKgDnj7ZboHhBPycq5WRs7qIDNsTB1K+CSM
dfQ7FDaF4abfvtpk5QIDAQAB
-----END PUBLIC KEY-----
El comando OpenSSL puede generar claves con diferentes algoritmos y tamaños. Por ejemplo, podríamos haber generado una con 2048. Verás que cambió bastante el tamaño de la clave privada.
openssl genrsa -out mysite.key 2048
cat mysite.key
-----BEGIN PRIVATE KEY-----
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDb7sWrKNtNMfkl
mFwiK9OikyKbaHzzSFiQldgr4FFwmLonbFyqWBDGfIlZFr7yKPEVs7YWtghkDNDx
qgbAuMm3+Q5C4zuiu0t2biP6zVz6c4PsYPZ+HRrkeSfDbMo2WMMa5KGf2rh/Bzsm
90+qItbcJMCg1l+/CMWK4TQFsSdt8YAKf4ZU6XV3xtFTtWnt59lfy/syYjWf2eAH
ATATXAqEi3qlUkpHf0qODQY8MoVPrD+HSRlQCCaBl2pMq+J18x3UPwMWPCKsF2FU
ihGgTbUSHdagYs8Mqy/7i5iKRoKsxu4znD15TF/4GuS/uJ7W3wwRodHOFGh/lYZq
FDA6i/yJAgMBAAECggEAAjAh7038wIvaurEFWaGt/VQRaBJmC9WQa//Ror4ckU4z
q+i8E0XFBPSAOU6sn6QgoeKj0R4Gf1hRS9YxMwGjoBzuM2QnV7sdSRRXb0tTvXog
ud1NFnwbpGJALwWKDXhcmIvlv71hUII16HFVbY/jK1WCRRdc5H2l2XfcGKJmjgVw
UXjVOL7643WKoJl62OfIg/aqcvMs4fA/VqQ9UWBzpsRibE6yfSzVvjKMFrJo3oN7
wN3RyYNtzS98cjLB0BTN0qEPVaKLQuA8VYEOq4/qwOC5LXLamJJCfQVxbvGqX/ew
vZKqOH7/slV4G5O0NE36OM7p3IWAWybkOfkCsm8KMQKBgQD9KpC1XBgOAzJHmqGz
eKMOinx/jZyWiCCPNH/Wy3Rg+Nu+XDtoE/KbL+NZQqKbxQZOg+bBYIE0gZjw6Txb
uwpo8dLrMSIaMokn6aFfks6BxbrQFoziwJP9q1L+omE7WXPmpkiqGGskWuok/XIa
YM3qEVjAdIXSrbFEqZK/00V2EwKBgQDeZPpStTR+DlNTe8iLHdsB5uhzKA+A0Jr5
Tr6dwCSClqqOd8Qd7rXxtf/xlzT9mKUNJVGYlxlGkYzA+PNyxOAbMWN4NghnuJM/
BEbcNuLOeJFVyKU36M9SAbhsNTTb4wEVMOW31J8xqt4fJt1gVcybaREM3Cm5r6KJ
qHYuqI6GcwKBgQC8Jx1jXG2YRHHi256f5uGwleYPWmztR4CDTe5Q8eath2axZJTW
NjURdxbNqQN3J4gXZFpkj9eW8VZ8fatZNXp4InmySFLjC3n6Ct3fTRljQ1QjAQ92
GtAiMGk/S+ldlY7Y9e59VCaU32izUxWxWw7OjlPavP8UY/iiYjDplhhCtwKBgHu8
00qRZ9N7RQF+Lea5hdFZGJx5/aY+avurxIMhFS9ThTIfkQ7WcoU6Ll3NM76l36+g
w/WSnI2XDimQWmPRBqAaqq2H4sVS/Rpi1spP/4HBs5t3N/YTosaODn6mW/K8Ky4P
NsFBnBGWcGAEz8d59Y3Ct6ngFZcrEdRl1tu/DQ3hAoGANdDNsZ6OJT0lD3UJb8UN
Jy0NPk5VgXFUDkMzdeAyepCfX3Q2WSw+jsutapqrO5DWP17eTgonqNsUHbCUxxCO
PQZaFTBKlQSI5+mMum3fl9DfDmcyjF7d6SEflrVIsnA5AKOj2bvf9O/y110yNMIq
JwDuCja1Pwfa12NARLsI+6A=
-----END PRIVATE KEY----
openssl rsa -in mysite.key -pubout > mysite.pem
cat mysite.pem
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2+7FqyjbTTH5JZhcIivT
opMim2h880hYkJXYK+BRcJi6J2xcqlgQxnyJWRa+8ijxFbO2FrYIZAzQ8aoGwLjJ
t/kOQuM7ortLdm4j+s1c+nOD7GD2fh0a5Hknw2zKNljDGuShn9q4fwc7JvdPqiLW
3CTAoNZfvwjFiuE0BbEnbfGACn+GVOl1d8bRU7Vp7efZX8v7MmI1n9ngBwEwE1wK
hIt6pVJKR39Kjg0GPDKFT6w/h0kZUAgmgZdqTKvidfMd1D8DFjwirBdhVIoRoE21
Eh3WoGLPDKsv+4uYikaCrMbuM5w9eUxf+Brkv7ie1t8MEaHRzhRof5WGahQwOov8
iQIDAQAB
-----END PUBLIC KEY-----
Pero nada de esto garantiza que el servidor al que estamos intentando acceder sea de hecho el servidor correcto. Un hacker puede tener un servidor y hospedar un sitio web idéntico haciéndose pasar por el servidor verdadero y enviar la clave pública de él para ti, y tú cifrarás los datos para él con la clave pública de él.
Vamos a imaginar que el hacker sea alguien que administra una red y simplemente alteró el servidor dns de la red para que apunte la dirección https://servidor.com al ip con el sitio web que él creó.
Es ahí que entra la necesidad de saber si la clave pública que recibiste es legítima o no.
Cuando recibimos la clave pública, no viene solo la clave pública; recibimos un certificado que contiene la clave pública. El certificado posee algunas informaciones que serán necesarias para validación.
En los ejemplos anteriores generamos la clave privada y después la clave pública usando la clave privada. Con este comando podemos usar la clave privada para generar un certificado y este contendrá la clave pública.
openssl req -x509 -new -key mysite.key -out certificado.pem
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]:BR
State or Province Name (full name) [Some-State]:ES
Locality Name (eg, city) []:Vila Velha
Organization Name (eg, company) [Internet Widgits Pty Ltd]:devsecops
Organizational Unit Name (eg, section) []:personal
Common Name (e.g. server FQDN or YOUR name) []:devsecops
Email Address []:[email protected]
cat certificado.pem
-----BEGIN CERTIFICATE-----
MIID9zCCAt+gAwIBAgIUfYH2ViX4fsY2IrO7fLfkNTp7uv0wDQYJKoZIhvcNAQEL
BQAwgYoxCzAJBgNVBAYTAkJSMQswCQYDVQQIDAJFUzETMBEGA1UEBwwKVmlsYSBW
ZWxoYTESMBAGA1UECgwJZGV2c2Vjb3BzMREwDwYDVQQLDAhwZXJzb25hbDESMBAG
A1UEAwwJZGV2c2Vjb3BzMR4wHAYJKoZIhvcNAQkBFg9kYXZpZEBnbWFpbC5jb20w
HhcNMjQwMjA0MTgxNzAzWhcNMjQwMzA1MTgxNzAzWjCBijELMAkGA1UEBhMCQlIx
CzAJBgNVBAgMAkVTMRMwEQYDVQQHDApWaWxhIFZlbGhhMRIwEAYDVQQKDAlkZXZz
ZWNvcHMxETAPBgNVBAsMCHBlcnNvbmFsMRIwEAYDVQQDDAlkZXZzZWNvcHMxHjAc
BgkqhkiG9w0BCQEWD2RhdmlkQGdtYWlsLmNvbTCCASIwDQYJKoZIhvcNAQEBBQAD
ggEPADCCAQoCggEBAKyVjzmLJsbi0zmon1NFYqzCn5gMSL6q5OfhtlBUxE8iDu4B
H+9eP6c8FK6rLuA5nNCTbUQj37d7rwekIjF1KN6+B+W/av/xkRi3mbBzIR73Iwhv
OatNz+XXJPDH9hxSa7VKKmJ/TG4GvkbForBrVCsMbcvlh1EN87HIT3nYUzB8QRX+
NDeiv4o3sEB8NwrWcO8cRwSLxUMr1iQSEQcpdBv4OH6paQkqyJM9KxoR7u0IYXSt
O61NBPfrHRXoGwJvkkVEay6acWj4CO+J+Ft9piy5wG/BlvKV9X3aGF72qS2Hipoe
qC+L/ICpviMZANW0lstNbgV6FbUS2/pGUNjzpqkCAwEAAaNTMFEwHQYDVR0OBBYE
FCdy2zrMEzzK3W6X9Bbbi1saMQowMB8GA1UdIwQYMBaAFCdy2zrMEzzK3W6X9Bbb
i1saMQowMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBAImSI9i1
Rr8BeDuPuPa4SxNROyR9mXO+UqAPnb1Omrtp8+4tfrs2lXLFYwcTMub4dHLeV30f
k9BJtpcbGvDyDy2yC/S4Nqn+wB1uKmjQFW8XBe4RCTRWUvWqC9CARUNGF5ABveN7
ZU+w7hg1hZI1AQiP/cz2Z/yPDZ+sgyrctmMrN2YJB47cErXNw2bcDd9TUBgdoI6A
ZtkvAmbRdKkc0yU7Q6aUDby5nunpV1B72hkX6dpg4WT8APem1KGG4h2ZXZlSKgC1
qzJaMqWLom47xcRSMM0CTCQDh37OPQlUNsOPyVcrVrSBhuXuqcDQ1NtoUfNGa/VU
oZY5Zwj/v1JYpak=
-----END CERTIFICATE-----
Abriendo ese archivo en el sistema podemos ver esto y más otras cosas que no cupieron en el print.

Este es un certificado autofirmado. Observa el campo Verified by: devsecops.
Si generaste el certificado tendrás que firmarlo tú mismo y nadie confía en ti, luego, este no es considerado un certificado seguro.
Podríamos generar un certificado diciendo que somos Amazon, pasar todos los datos necesarios en nombre de ella.
¿Qué prueba que un sitio es quien dice ser?
Mirando más de cerca un certificado de amazon.com por ejemplo tenemos:

Ahora un certificado como el de amazon tenemos Issued By DigiCert Global CA G2. O sea alguien que no es amazon comprobó que ese certificado es legal.
Es ahí que entra la parte más importante de todas: ¿quién firmó y emitió el certificado?
El navegador ya hace ese trabajo para ti. Verifica quién firmó y emitió el certificado y, en caso de que no sea una Autoridad Certificadora (CA) reconocida, dirá que ese certificado no es válido, por lo tanto la página no será segura.
Varias CAs existen y pueden firmar un certificado.
Y muchos otros...
Para generar un certificado legítimo y pagar por él es necesario crear un CSR (Certificate Signing Request), o Solicitud de Firma de Certificado, es un bloque de datos codificado que es generado por una entidad que solicita un certificado digital. Un CSR contiene las informaciones públicas asociadas a una clave pública para la cual el certificado será emitido.
Cuando deseas obtener un certificado digital, necesitas generar un CSR y enviarlo a una Autoridad Certificadora (CA) confiable para firma. La CA usa las informaciones en el CSR para crear un certificado digital que vincula la clave pública proporcionada en el CSR a un determinado titular (como un dominio o una organización).
Para generar un CSR el comando es el siguiente.
openssl req -new -key mysite.key -out mysite.csr
# Respondemos algunas preguntas...
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]:BR
State or Province Name (full name) [Some-State]:ES
Locality Name (eg, city) []:Vila Velha
Organization Name (eg, company) [Internet Widgits Pty Ltd]:devsecops.puziol.com.br
Organizational Unit Name (eg, section) []:devsecops
Common Name (e.g. server FQDN or YOUR name) []:devsecops.puziol.com.br
Email Address []:[email protected]
Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:mypass
An optional company name []:devsecops
cat mysite.csr
-----BEGIN CERTIFICATE REQUEST-----
MIIDHjCCAgYCAQAwgacxCzAJBgNVBAYTAkJSMQswCQYDVQQIDAJFUzETMBEGA1UE
BwwKVmlsYSBWZWxoYTEgMB4GA1UECgwXZGV2c2Vjb3BzLnB1emlvbC5jb20uYnIx
EjAQBgNVBAsMCWRldnNlY29wczEgMB4GA1UEAwwXZGV2c2Vjb3BzLnB1emlvbC5j
b20uYnIxHjAcBgkqhkiG9w0BCQEWD2RhdmlkQGdtYWlsLmNvbTCCASIwDQYJKoZI
hvcNAQEBBQADggEPADCCAQoCggEBAKyVjzmLJsbi0zmon1NFYqzCn5gMSL6q5Ofh
tlBUxE8iDu4BH+9eP6c8FK6rLuA5nNCTbUQj37d7rwekIjF1KN6+B+W/av/xkRi3
mbBzIR73IwhvOatNz+XXJPDH9hxSa7VKKmJ/TG4GvkbForBrVCsMbcvlh1EN87HI
T3nYUzB8QRX+NDeiv4o3sEB8NwrWcO8cRwSLxUMr1iQSEQcpdBv4OH6paQkqyJM9
KxoR7u0IYXStO61NBPfrHRXoGwJvkkVEay6acWj4CO+J+Ft9piy5wG/BlvKV9X3a
GF72qS2HipoeqC+L/ICpviMZANW0lstNbgV6FbUS2/pGUNjzpqkCAwEAAaAxMBUG
CSqGSIb3DQEJBzEIDAZteXBhc3MwGAYJKoZIhvcNAQkCMQsMCWRldnNlY29wczAN
BgkqhkiG9w0BAQsFAAOCAQEAqdM/RmCkIuMAIFcqK6nb4+dJfNXtmggv+0yLZu0K
ccN1STg4XgttfvR1ZJAS38IUEWSEUIJ7K4nkxdUDZnxoXFEFpzN5PKpdp6/i3Sv2
o6xp7uWQhIs08zeg5MA4wuKjcNMev58zv7w4YTQNlhZzJj6mtWIWTkb2y5XYwLeV
1vHz6vqbb2TE+UFNmBteX0q+QOK63ymoODVNBTss36c05Hs6pr8WYAN6nNIK3HcK
/b015LP6J6AdZGx3CXDxc+UDRMn1W0vG86/yduRqMZmeUTE/BD7l5PoFxZwnUJqX
j+PtE66Cj5z6duvO4qa/hdQmT/R+DR7QOTEbsDMrdSKKUg==
-----END CERTIFICATE REQUEST-----
# Podemos también pasar todos los parámetros en el comando
# C = Country
# ST = State
# O = Organization
# CN = Common Name
openssl req -new -key mysite.key -out mysite.csr -subj "/C=BR/ST=ES/O=devsecops/CN=devsecops.puziol.com.br"
Ese archivo generado .csr debe ser enviado a la autoridad certificadora para firma. La CA posee su propia clave pública y privada. Una curiosidad es que ese tipo de servidor de firma necesita ser guardado con una seguridad máxima pues si su clave privada es expuesta todos los certificados deberán ser invalidados automáticamente.
La CA conferirá los datos y enviará de vuelta el certificado emitido firmado con la clave privada de ella. Ahora tendremos un certificado que el navegador confiará.
Pero ¿cómo el navegador sabe que fue firmado por una CA legítima y no una CA falsa?
Dentro de los navegadores tenemos varias claves públicas built-in de las CAs legítimas.

Vale recordar que esas son CA públicas que nos ayudan a validar sitios públicos. Estas autoridad no consiguen hacer la validación de un sitio que esté en una red privada de la organización.
La mayoría de las CA poseen servicios que pueden ser deployados internamente como un Servidor CA internamente dentro de la empresa. Sin embargo, podemos crear nuestras propia CA para firmar los certificados internos e instalarla en los navegadores.
Por fin, pero no menos importante, está la cuestión de cómo el servidor puede garantizar la autenticidad del usuario. Es esencial proteger contra posibles ataques de hackers que puedan hacerse pasar por otra persona interceptando el tráfico de datos.
Varios servicios fiscales del gobierno necesitan que las empresas posean sus certificados para probar sus identidad a la hora de comunicarse con sus servidores. El servidor requisita el certificado del cliente para saber que él es de hecho quien dice ser. Por eso también es necesario instalar esos certificados en la máquina del cliente.
Toda esa infraestructura creada es conocida como PKI (Public Key Infrastructure).
Generalmente los certificados con clave pública poseen los siguientes nombres.
Certificado con public key.
- server.crt
- server.pem
- client.crt
- client.pem
Claves privadas generalmente poseen la palabra key como extensión o parte del nombre.
- server.key
- server-key.pem
- client.key
- client-key.pem
Pero si conferimos lo que tenemos dentro podemos ver la diferencia ya en el inicio en el archivo.
-
-----BEGIN PRIVATE KEY-----
-
-----BEGIN PUBLIC KEY-----
-
-----BEGIN CERTIFICATE-----