Pular para o conteúdo principal

TLS Fundamentos

Um certificado é usado para garantir a confiança entre duas partes durante uma transação.

Quando um usuário tenta acessar um servidor da web, os certificados tls garantem que a comunicação entre o user e o server seja criptografada e que o servidor e o user seja quem diz ser.

Se um usuário enviasse suas credenciais sem criptografia um hacker com um simples sniffer seria capaz de recuperar as credenciais farejando o tráfego da rede e invadir a conta do usuário.

Uma vez criptografado os dados, ele será embaralhado e somente quem tem a chave conseguirá decifrá-los, caso alguém fareje a rede esses dados não farão sentido algum.

Se a chave para descriptografar precisa ser enviada para o servidor pela mesma rede então não faria sentido nenhum, pois essa chave poderia também ser interceptada no caminho e seria usada para descriptografar os dados.

O sistema em que ambos os lados conhecem a chave de criptografia é chamada de criptografia simétrica. A mesma chave usada para encriptar é usada para desencriptar.

A criptografia assimétrica é quando um par de chaves (duas chaves), uma chave PÚBLICA que encripta os dados (conhecida por todos) e outra chave PRIVADA (conhecida somente pelo destinatário) que decodifica os dados. Quando queremos enviar algo para encriptamos o conteúdo com a sua chave PÚBLICA, e somente o destinatário conseguirá desencriptar usando sua chave PRIVADA.

Já fazemos todos esse processo no Github, GitLab, ssh, etc.

Se você não possui uma par de chaves para ssh está na hora de ter um.

ssh-keygen

O comando acima irá gerar um par de chaves para propósito de ssh.

  • id_rsa: é a chave privada que somente você deve conhecer
  • id_rsa.pub: é sua chave pública que você pode colocar no github, GitLab, nos servidores que você acessa via ssh, etc.

Sabendo desse cenário, quando acessamos um servidor via https no navegador por exemplo, o servidor envia automaticamente a chave pública dele para o navegador do usuário. O navegador cria uma chave de criptografia simétrica (ele já está sabendo qual é) criptografa com a chave pública do servidor e envia de volta para ele. Somente o servidor é capaz de descriptografar isso com a sua chave privada. Logo ambos conhecerão a uma chave simétrica sem que ninguém mais conheça e a partir desse momento é possível criptografar tudo somente usando a chave simétrica.

Uma coisa importante sobre o par de chaves assimétricas; se você encriptar algo com a chave pública, somente a chave privada desencriptará. Não é possível desencriptar usando a mesma chave publica algo que você encriptou com ela. Se encriptar algo com suas chave privada a chave pública conseguira desencriptar e todos conhecem a chave pública. Por isso é necessário que tudo que vá para você seja encriptado com sua chave pública e o que irá para outros encriptar com a chave pública deles e não com a sua própria.

Para gerar um par de chaves de propósito ssl o comando é um pouco 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-----

o comando openssl pode gerar chaves com diferentes algoritmos e tamanhos. por exemplo poderíamos ter gerado uma com 2048. Veja que mudou bastante o tamanho da 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-----

Mas nada disso garante que o servidor que estamos tentando acessar é de fato o servidor correto. Um hacker pode ter um servidor e hospedar um website idêntico se passando pelo servidor verdadeiro e enviar a chave pública dele pra você e você criptografará os dados para ele com a chave pública dele.

Vamos imaginar que o hacker seja alguém que administra uma rede e ele simplesmente aponta faz com que o servidor dns da rede aponte o https://servidor.com para o ip com o website que ele criou.

É ai que entra o momento que saber se a chave pública que você recebeu é legítima ou não.

Quando recebemos a chave pública, não vem somente a chave pública, recebemos um certificado e dentro deste contém a chave pública. No caso o certificado possui algumas informações que serão necessárias para validar algumas informações.

Antes geramos a chave privada e depois a chave publica usado a chave privada. Com este comando podemos usar a chave privada para gerar um certificado e este conterá a chave 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-----

Abrindo esse arquivo no sistema podemos ver isso e mais outras coisas que não couberam no print.

Alt text

Esse é um certificado auto assinado. Observe o campo Verified by: devsecops.

Se você gerou o certificado você terá que assiná-lo você mesmo e ninguém confia em você, logo.. esse não é considerado um certificado seguro.

Poderíamos gerar um certificado dizendo que somos a Amazon, passar todos os dados necessários em nome dela.

O que prova que um site é quem diz ser?

Olhando mais de perto um certificado da amazon.com por exemplo temos:

Alt text

Agora um certificado como o da amazon temos Issued By DigiCert Global CA G2. Ou seja alguém que não é a amazon comprovou que esse certificado é legal.

É ai que entra a parte mais importante de todas, Quem assinou e emitiu o certificado?

O navegador já faz esse trabalho para você. Ele verifica quem assinou e emitiu o certificado e caso não seja uma Autoridade Certificadora (CA) ele dirá que esse certificado não é válido, portanto a página não será segura.

Várias CAs existem e podem assinar um certificado.

e muitos outros...

Para gerar um certificado legítimo e pagar por ele é necessário criar um CSR (Certificate Signing Request), ou Solicitação de Assinatura de Certificado, é um bloco de dados codificado que é gerado por uma entidade que solicita um certificado digital. Um CSR contém as informações públicas associadas a uma chave pública para a qual o certificado será emitido.

Quando você deseja obter um certificado digital, você precisa gerar um CSR e enviá-lo para uma Autoridade Certificadora (CA) confiável para assinatura. A CA usa as informações no CSR para criar um certificado digital que vincula a chave pública fornecida no CSR a um determinado titular (como um domínio ou uma organização).

Para gerar um CSR o comando é o seguinte.

openssl req -new -key mysite.key -out mysite.csr

# Respondemos algumas perguntas...
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 também passar todos os parâmetros no 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"

Esse arquivo gerado .csr deve ser enviado a autoridade certificadora para assinatura. Uma CA possua sua chave pública e privada. Uma curiosidade é que esse tipo de servidor de assinatura precisa ser guardado com uma segurança máxima pois se sua chave privada for exposta todos os certificados deverão ser invalidados automaticamente.

A CA irá conferir os dados e enviará de volta o certificado emitido assinado com a chave privada. Agora teremos um certificado que o navegador confiará.

Mas como o navegador sabe que foi assinado por uma CA legítima e não uma CA fake?

Dentro dos navegadores temos várias chaves públicas built-in das CAs legítimas.

Alt text

Vale lembrar que um que essas são CA públicas que nos ajudam a validar sites públicos. Essas autoridade não conseguem fazer a validação de um site que esteja em uma rede privada da organização.

A maioria das CA possuem serviços que podem ser deployados internamente como um Servidor CAA internamente dentro da empresa. Porém, podemos criar nossas própria CA para assinar os certificados internos e instalá-la nos navegadores.

E por último e não menos importante é como o servidor garante que o usuário é quem diz ser? Poderia ser um hacker se passando por alguém interceptando o tráfego de alguma maneira.

Vários serviços fiscais do governo precisam que as empresas possuem seus certificados para provar suas identidade na hora de se comunicar com seus servidores. O servidor requisita o certificado do cliente para saber que ele é de fato quem diz ser. Por isso também é necessário instalar esses certificados no máquina do cliente.

Toda essa infraestrutura criada é conhecida como PKI (Public Key Infrastructure).

Geralmente os certificados com chave pública possuem os seguintes nomes.

Certificado com public key.

  • server.crt
  • server.pem
  • client.crt
  • client.pem

Chaves privadas geralmente possuem a palavra key como extensão ou parte do nome.

  • server.key
  • server-key.pem
  • client.key
  • client-key.pem

Mas se conferir o que temos dentro podemos ver a diferença já no início no arquivo.

  • -----BEGIN PRIVATE KEY-----

  • -----BEGIN PUBLIC KEY-----

  • -----BEGIN CERTIFICATE-----