Fundamentos TLS
Un certificado se usa 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 enviase sus credenciales sin cifrado, un hacker con un simple sniffer sería capaz de recuperar las credenciales rastreando el tráfico de la red e invadir la cuenta del usuario.
Una vez cifrados los datos, serán mezclados y solamente quien tenga la clave conseguirá descifrarlos, en caso de que alguien rastree la red esos datos no tendrán sentido alguno.
Si la clave para descifrar necesita ser enviada al servidor por la misma red entonces no tendría sentido ninguno, pues esa clave podría también ser interceptada en el camino y sería usada para descifrar los datos.
El sistema en que ambos lados conocen la clave de cifrado se llama cifrado simétrico. La misma clave usada para cifrar se usa para descifrar.
El cifrado asimétrico es cuando un par de claves (dos claves), una clave PÚBLICA que cifra los datos (conocida por todos) y otra clave PRIVADA (conocida solamente por el destinatario) que decodifica los datos. Cuando queremos enviar algo ciframos el contenido con su clave PÚBLICA, y solamente el destinatario conseguirá descifrar usando su clave PRIVADA.
Ya hacemos todo ese proceso en Github, GitLab, ssh, etc.
Si no posees un par de claves para ssh es hora de tener uno.
ssh-keygen
El comando arriba generará un par de claves para propósito de ssh.
- id_rsa: es la clave privada que solamente 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 ese escenario, cuando accedemos a un servidor vía https en el navegador por ejemplo, el servidor envía automáticamente su clave pública al navegador del usuario. El navegador crea una clave de cifrado simétrico (él ya está sabiendo cuál es) cifra con la clave pública del servidor y envía de vuelta para él. Solamente el servidor es capaz de descifrar eso 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 solamente usando la clave simétrica.
Una cosa importante sobre el par de claves asimétricas; si cifras algo con la clave pública, solamente la clave privada descifrará. No es posible descifrar usando la misma clave pública algo que cifraste con ella. Si cifras algo con tu clave privada la clave pública conseguirá descifrar y todos conocen la clave pública. Por eso es necesario que todo lo que vaya para ti sea cifrado con tu clave pública y lo que irá para otros cifrar con la clave pública de ellos y no con tu propia.
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 private key.
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 es de hecho el servidor correcto. Un hacker puede tener un servidor y alojar un sitio web idéntico haciéndose pasar por el servidor verdadero y enviar su clave pública para ti y tú cifrarás los datos para él con su clave pública.
Vamos a imaginar que el hacker sea alguien que administra una red y simplemente hace que el servidor DNS de la red apunte https://servidor.com hacia la IP con el sitio web que él creó.
Es ahí donde entra el momento de saber si la clave pública que recibiste es legítima o no.
Cuando recibimos la clave pública, no viene solamente la clave pública, recibimos un certificado y dentro de este contiene la clave pública. En el caso el certificado posee algunas informaciones que serán necesarias para validar algunas informaciones.
Antes 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 la captura.

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í donde 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) dirá que ese certificado no es válido, por 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. Una CA posee su 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. Ahora tendremos un certificado en el que el navegador confiará.
Pero ¿cómo sabe el navegador que fue firmado por una CA legítima y no una CA falsa?
Dentro de los navegadores tenemos varias claves públicas integradas de las CAs legítimas.

Vale recordar que estas son CA públicas que nos ayudan a validar sitios públicos. Estas autoridades 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 desplegados internamente como un Servidor CA internamente dentro de la empresa. Sin embargo, podemos crear nuestra propia CA para firmar los certificados internos e instalarla en los navegadores.
Y por último y no menos importante es ¿cómo garantiza el servidor que el usuario es quien dice ser? Podría ser un hacker haciéndose pasar por alguien interceptando el tráfico de alguna manera.
Varios servicios fiscales del gobierno necesitan que las empresas posean sus certificados para probar sus identidades a la hora de comunicarse con sus servidores. El servidor requiere 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 verificas lo que tenemos dentro podemos ver la diferencia ya en el inicio en el archivo.
-
-----BEGIN PRIVATE KEY-----
-
-----BEGIN PUBLIC KEY-----
-
-----BEGIN CERTIFICATE-----