Criptografia em AdvPL – Parte 12

Introdução

No post anterior vimos as dicas de ouro de uso da OpenSSL !! Agora, vamos ver um pouco mais sobre os certificados digitais, e as funções do AdvPL de manipulação / conversão de certificados e chaves. Para ver tudo o que já foi publicado nessa série de posts, acesse o link Criptografia e Segurança.

Funções AdvPL para manipulação de Certificados Digitais

No Post 01, vimos uma lista de funções do AdvPL para manipulação de certificados digitais e chaves criptográficas. O objetivo desse grupo de funções é obter algumas informações dos certificados, e realizar a conversão de certificados e chaves de diversos formatos para o formato PEM — usado e suportado pelo TOTVS Application Server e seus componentes.

Função AdvPL PEMInfo()

Documentada no TDN no link http://tdn.totvs.com/display/tec/PEMInfo, essa função permite recuperar algumas informações de um certificado digital armazenado no formado codificado em Base64  (formato PEM/CRT), como a versão do certificado, validade (de-até), emissor, destinatário ou assunto, número serial e Thumbprint ou Fingerprint do certificado (representados em Base64 e hexadecimal). Vamos ver o que ela retorna quando executamos um fonte de testes que abre aquele certificado digital que geramos no Post 06 usando o fonte abaixo:

User Function PemInfo()
Local nI,nJ
Local cFile := '\certificates\note-juliow-ssd.cer'
Local aRet
Conout('Arquivo ......... '+cFile)
aRet := PemInfo(cFile)
Conout('Certificados .... '+cValToChar(len(aRet)))
For nI := 1 to len(aRet)
  Conout('Certificado ['+cValToChar(nI)+']')
  For nJ := 1 to len(aRet[nI])
    conout('['+cValToChar(nJ)+'] '+cValToChar(aRet[nI][nJ]))
  Next 
Next
Return

Antes de executar este código, crie uma pasta chamada “certificates” a partir do rootpath do ambiente, e copie o certificado a ser verificado para dentro dela. Não precisa copiar a chave (key), apenas o certificado. Ao executar o programa usando o certificado gerado anteriormente, o resultado no log de console foi:

Arquivo ......... \certificates\note-juliow-ssd.cer
Certificados .... 1
Certificado [1]
[1] 2
[2] /C=BR/ST=SP/L=Sao Paulo/O=Tudo em AdvPL/CN=note-juliow-ssd
[3] /C=BR/ST=SP/L=Sao Paulo/O=Tudo em AdvPL/CN=note-juliow-ssd
[4] 190816000619Z
[5] 200815000619Z
[6] 540424256993644162400613528322498278498171836889
[7] UVSmBFw2nXziHOJ2wivsBfqRjwg=
[8] 5154a6045c369d7ce21ce276c22bec05fa918f08

Um arquivo pode conter mais de um certificado. Logo, o array retornado sempre é multi-dimensional, onde cada elemento contém um array com 8 propriedades do certificado. No nosso caso, o arquivo contém apenas um certificado. Cada elemento retornado no array indica uma propriedade do certificado:

Índice

Tipo

Dado

1 N Versão (0=Versão 1, 1=Versão 2, 2=Versão 3)
2 C Destinatário (Subject)
3 C Emissor (Issuer)
4 C Data de Validade Inicial
5 C Data de Validade Final
6 C Número serial
7 C Fingerprint/Thumbprint (Base64)
8 C Fingerprint/Thumbprint (Hexadecimal)

Observações

  • As datas de validade inicial e final são retornadas no formado “AAMMDDhhmmssZ” (ano,mes,dia,hora,minuto e segundo, todos com 2 dígitos e o sufixo “Z”, que identifica uma hora universal (GMT).
  • O número serial (índice 5) parece estar sendo retornado com um valor decimal.
  • Os valores do Fingerprint/ThumbPrint são calculados para o certificado — usando SHA1 por default — e retornados em duas formas: Hexadecimal e Base64. Caso seja necessário retornar esta informação usando outro algoritmo de hash, basta especificar o algoritmo desejado no terceiro parâmetro da função.

Usando a OpenSSL

Podemos utilizar o comando abaixo da OpenSSL para ler as informações do certificado:

openssl x509 -in note-juliow-ssd.cer -noout -text -fingerprint

E com ele obtemos o resultado abaixo:

Version: 3 (0x2)
Serial Number:
5e:a9:76:38:db:c0:3c:5e:cf:f6:8b:e0:cf:7c:b8:5c:ad:87:59:d9
Issuer: C = BR, ST = SP, L = Sao Paulo, O = Tudo em AdvPL, CN = note-juliow-ssd
Validity
Not Before: Aug 16 00:06:19 2019 GMT
Not After : Aug 15 00:06:19 2020 GMT
Subject: C = BR, ST = SP, L = Sao Paulo, O = Tudo em AdvPL, CN = note-juliow-ssd
SHA1 Fingerprint=51:54:A6:04:5C:36:9D:7C:E2:1C:E2:76:C2:2B:EC:05:FA:91:8F:08

Função AdvPL WriteRSAPK()

Documentada no TDN no link http://tdn.totvs.com/display/tec/WriteRSAPK, a função WriteRSAPK() foi criada para permitir a conversão de uma chave privada no formato DER para PEM, bastando informar onde está o arquivo com a chave privada de origem, e onde deve ser gerada a chave de destino.

Uma chave privada ou mesmo um certificado digital são salvos em disco normalmente usando dois formatos:

  • Arquivo texto codificado em Base64 — formato PEM
  • Arquivo ASCII binário — Formato DER

Os formatos PEM são usados por exemplo em servidores Apache e similares, enquanto o formato DER é usado em aplicações Java. O conteúdo da chave privada é o mesmo, o que muda é a forma de representação da chave do arquivo. Como os formatos de certificados e chaves no TOTVS Application Server são os do Apache (PEM), todas as demais funções de conversão de certificados e chaves do AdvPL até o momento convertem informações, certificados e chaves de outros formatos ( PKCS, PFX, DER ) para PEM.

Funções de suporte ao formato PFX/PKCS12

O formato PFX (ou PKCS12) — usado pelo Windows / IIS por exemplo — é um container que permite encapsular — dentro do mesmo aquivo — por exemplo um ou mais certificados digitais, certificado(s) da cadeia de autenticação, chaves privadas e outros. Para facilitar a extração e conversão destas informações de um arquivo no formato PFX para PEM, o AdvPL disponibiliza as seguintes funções:

E, adicionalmente, para obter a lista de informações que estão dentro de um determinado arquivo PFX, temos também a função PFXInfo – http://tdn.totvs.com/display/tec/PFXInfo. Esta função retorna apenas informações básicas sobre o certificado principal e o(s) certificados da Autoridade Certificadora — quando presentes — do arquivo, como por exemplo a verão do certificado, emissor, destinatário e datas de validade inicial e final.

Todas as funções acima têm em comum o arquivo PFX a ser avaliado e um parâmetro opcional de senha, que deve ser utilizado quando o arquivo PFX estiver protegido por senha. E, claro, a função somente obterá sucesso se o arquivo PFX utilizado tiver a informação que será extraída 😀

Formatos PKCS7 (P7B) e PKCS8

Além dos formatos já vistos, ainda temos o PKCS e PKCS8, que podem ser usados para guardar uma chave privada. Para extrair a chave privadas destes formatos para o formato PEM em AdvPL, podemos usar as funções abaixo:

Conclusão

Agora que já vimos hash criptográfico, uso de certificados da infra-estrutura do TOTVS Application Server — HTTPS e conexão segura com SmartClient, nos próximos posts serão abordadas funcionalidades de assinatura digital usando o AdvPL 😀

Agradeço novamente a audiência e lhes desejo TERABYTES DE SUCESSO !!!

Referências

 

Criptografia em AdvPL – Parte 11

Introdução

Até agora vimos alguns exemplos de uso da OpenSSL para realizar operações com certificados e chaves. Agora, vamos dar uma repassada nas funcionalidades da ferramenta, e ver algumas considerações e dicas de utilização 😀 Para acessar o índice com todas as publicações sobre o tema Criptografia em AdvPL, acesse o link Criptografia e Segurança

OpenSSL

Em posts anteriores, vimos como instalar uma versão da OpenSSL já “pronta” para Windows, e utilizamos vários comandos para os exemplos de certificados e chaves. Mas não chegamos nem perto de ver tudo o que ela pode fazer. Meu objetivo não é dar um curso de OpenSSL, mas sim compartilhar as fontes de busca que eu usei, e as conclusões que eu cheguei nesta primeira semana de uso da ferramenta.

OpenSSL tem muito mais do que apenas a linha de comandos

Quando instalamos por exemplo a OpenSSL completa no Windows, não temos apenas a linha de comandos, mas também os arquivos necessários para você criar por exemplo um projeto em C++ usando um compilador ou ferramenta de sua preferência para usar as funções da LIB OPENSSL, que já vêm com versões prontas para uso, com os respectivos arquivos de include — para usar as funções e os tipos de dados declarados na biblioteca.

A aplicação via linha de comandos faz muita coisa

Em todos os exemplos até o momento, usamos as chamadas da OpenSSL para realizar tarefas específicas através de argumentos. Existe uma relação enorme de funcionalidades, e também existe o modo “interativo”, onde executamos a openssl sem nenhum parâmetro, e ela nos oferece um interpretador de comandos para realizar diversas operações interativas, como por exemplo estabelecer uma conexão segura com um provedor de emails (POP, IMAP, SMPT), testar a aderência de um certificado em  uma conexão segura com um Web Service usando HTTPS com autenticação mútua, etc…

Pequeno resumo de operações

Quando executamos o comando “openssl help“, temos uma ideia de tudo o que dá pra fazer …

Standard commands
asn1parse ca ciphers cms
crl crl2pkcs7 dgst dhparam
dsa dsaparam ec ecparam
enc engine errstr gendsa
genpkey genrsa help list
nseq ocsp passwd pkcs12
pkcs7 pkcs8 pkey pkeyparam
pkeyutl prime rand rehash
req rsa rsautl s_client
s_server s_time sess_id smime
speed spkac srp storeutl
ts verify version x509

Message Digest commands (see the `dgst' command for more details)
blake2b512 blake2s256 gost md4
md5 mdc2 rmd160 sha1
sha224 sha256 sha3-224 sha3-256
sha3-384 sha3-512 sha384 sha512
sha512-224 sha512-256 shake128 shake256
sm3

Cipher commands (see the `enc' command for more details)
aes-128-cbc aes-128-ecb aes-192-cbc aes-192-ecb
aes-256-cbc aes-256-ecb aria-128-cbc aria-128-cfb
aria-128-cfb1 aria-128-cfb8 aria-128-ctr aria-128-ecb
aria-128-ofb aria-192-cbc aria-192-cfb aria-192-cfb1
aria-192-cfb8 aria-192-ctr aria-192-ecb aria-192-ofb
aria-256-cbc aria-256-cfb aria-256-cfb1 aria-256-cfb8
aria-256-ctr aria-256-ecb aria-256-ofb base64
bf bf-cbc bf-cfb bf-ecb
bf-ofb camellia-128-cbc camellia-128-ecb camellia-192-cbc
camellia-192-ecb camellia-256-cbc camellia-256-ecb cast
cast-cbc cast5-cbc cast5-cfb cast5-ecb
cast5-ofb des des-cbc des-cfb
des-ecb des-ede des-ede-cbc des-ede-cfb
des-ede-ofb des-ede3 des-ede3-cbc des-ede3-cfb
des-ede3-ofb des-ofb des3 desx
idea idea-cbc idea-cfb idea-ecb
idea-ofb rc2 rc2-40-cbc rc2-64-cbc
rc2-cbc rc2-cfb rc2-ecb rc2-ofb
rc4 rc4-40 seed seed-cbc
seed-cfb seed-ecb seed-ofb sm4-cbc
sm4-cfb sm4-ctr sm4-ecb sm4-ofb

Logo de cara são pelo menos 48 comandos, cada um deles abre um leque de opções. Para ver por exemplo o que pode fazer o comando x509 ou qualquer outro comando, use a sintaxe openssl <comando> -help, por exemplo:

openssl x509 -help
Usage: x509 [options]
Valid options are:
-help Display this summary
-inform format Input format - default PEM (one of DER or PEM)
-in infile Input file - default stdin
-outform format Output format - default PEM (one of DER or PEM)
-out outfile Output file - default stdout
-keyform PEM|DER Private key format - default PEM
-passin val Private key password/pass-phrase source
-serial Print serial number value
-subject_hash Print subject hash value
-issuer_hash Print issuer hash value
-hash Synonym for -subject_hash
-subject Print subject DN
-issuer Print issuer DN
-email Print email address(es)
-startdate Set notBefore field
-enddate Set notAfter field
-purpose Print out certificate purposes
-dates Both Before and After dates
-modulus Print the RSA key modulus
-pubkey Output the public key
-fingerprint Print the certificate fingerprint
-alias Output certificate alias
-noout No output, just status
-nocert No certificate output
-ocspid Print OCSP hash values for the subject name and public key
-ocsp_uri Print OCSP Responder URL(s)
-trustout Output a trusted certificate
-clrtrust Clear all trusted purposes
-clrext Clear all certificate extensions
-addtrust val Trust certificate for a given purpose
-addreject val Reject certificate for a given purpose
-setalias val Set certificate alias
-days int How long till expiry of a signed certificate - def 30 days
-checkend intmax Check whether the cert expires in the next arg seconds
Exit 1 if so, 0 if not
-signkey infile Self sign cert with arg
-x509toreq Output a certification request object
-req Input is a certificate request, sign and output
-CA infile Set the CA certificate, must be PEM format
-CAkey val The CA key, must be PEM format; if not in CAfile
-CAcreateserial Create serial number file if it does not exist
-CAserial val Serial file
-set_serial val Serial number to use
-text Print the certificate in text form
-ext val Print various X509V3 extensions
-C Print out C code forms
-extfile infile File with X509V3 extensions to add
-rand val Load the file(s) into the random number generator
-writerand outfile Write random data to the specified file
-extensions val Section from config file to use
-nameopt val Various certificate name options
-certopt val Various certificate text options
-checkhost val Check certificate matches host
-checkemail val Check certificate matches email
-checkip val Check certificate matches ipaddr
-CAform PEM|DER CA format - default PEM
-CAkeyform format CA key format - default PEM
-sigopt val Signature parameter in n:v form
-force_pubkey infile Force the Key to put inside certificate
-next_serial Increment current certificate serial number
-clrreject Clears all the prohibited or rejected uses of the certificate
-badsig Corrupt last byte of certificate signature (for test)
-* Any supported digest
-subject_hash_old Print old-style (MD5) issuer hash value
-issuer_hash_old Print old-style (MD5) subject hash value
-engine val Use engine, possibly a hardware device
-preserve_dates preserve existing dates when signing

Quer ver TUDO o que pode ser feito com linhas de comando na OPENSS ? Acesse a documentação oficial no Acesse o link https://wiki.openssl.org/index.php/Command_Line_Utilities, ele começa com um overview e alguns exemplos mais comuns, e no final da página, um índice para a documentação completa de cada comando disponível. Lembre-se de verificar qual a versão da OpenSSL que você está usando ( use o comando openssl version ), pois alguns parâmetros ou propriedades podem ter sido descontinuados ou implementados apenas em uma versão superior

openssl version
OpenSSL 1.1.1c 28 May 2019

Dica de Ouro 01

Como as especificações de segurança, certificados, chaves e afins são imensas, embora muita coisa possa ser feita com diversos parâmetros em linhas de comando, existem configurações default para várias operações pré-definidas no arquivo de configuração da openssl — normalmente um arquivo chamado  “openssl.cfg” ou “openssl.cnf”, dependendo da definição ou ausência da variável de ambiente OPENSSL_CONF que aponte para um arquivo default de configuração.

Quando você vai realizar determinadas operações, como emissão de certificados, assinaturas, chaves e afins para contextos diferentes, é muito interessante você criar seus arquivos de configuração, alterá-los e acrescentar as demais definições que você precisa dentro deles. Boa parte dos comandos que dependem de configuração aceitam o parâmetro “-config <configfile>“, onde podemos informar qual arquivo de configurações que deve ser utilizado. Isso diminui muito a necessidade de parâmetros adicionais nos comandos, mas ainda assim permite especificar parâmetros adicionais que, quando informados, têm precedência sobre os parâmetros de linha.

Dica de Ouro 02

Muitos parâmetros em linha de comando são comuns a muitos comandos, como -in , -out , -text, -noout — usados respectivamente para especificar um ou mais arquivos de entrada, um arquivo de saída, um formato de sai da em modo texto e inibir a saída de um resultado no console, por exemplo.

 openssl pkey -in private-key.pem -text

Usamos o comando pkey, para lidar com chaves privadas, especificamos que vamos usar como entrada (in) o arquivo private-key.pem, e queremos o resultado em formato texto. Ao executar este comando em uma chave privada previamente gerada, o resultado em tela vai a chave privada usada como entrada, e depois todos os dados da chave. Se quisermos uma saída onde a chave de entrada não seja mostrada, usamos o parâmetro “-noout”.

Dica de Ouro 03

Meu chapa, OPENSSL não é um projeto que nasceu ontem, têm documentação a rodo na internet. Quem já passou por algum apuro pra tentar fazer algo funcionar normalmente compartilha o embrolho e a resposta. Pergunte para o “Mestre Google”, que ele vai encontrar ou te levar para perto de onde está a resposta. Stack Overflow, blogs, inúmeros how-to estão disponíveis. Tudo o que eu compartilhei com vocês nesses últimos posts sobre criptografia e OpenSSL eu aprendi com pesquisas de múltiplas fontes e testes de prova de conceito.

A grande sacada é você não tentar entender tudo de uma vez, o “tudo” é grande demais, a Wikipedia tem páginas e mais páginas sobre todos esses assuntos. Não se limite a pesquisar na Wiki em Português, normalmente os conteúdos são bem mais superficiais do que o mesmo assunto na Wiki em inglês. Quando eu comecei a apender Clipper, literalmente no século passado, o guia de funções e comandos era inteiro em Inglês, e a Internet ainda não tinha chego por aqui …. Logo, meu dicionário de inglês-português era item permanente na minha mesa. Hoje você tem Internet e o Google Translator, use-os !!!

Se uma especificação completa parece complicada, encontre uma fonte de informação menos abrangente, ou que transmita o conceito. A infraestrutura de chaves criptográficas é enorme, mas quando você entende um minimo sobre as partes básicas envolvidas, o resto são propriedades e derivações sobre a mesma base. Toda a linguagem de programação tem IF e LOOP, o que muda é a sintaxe.

Dica de Ouro 04

Qualquer conhecimento é melhor assimilado se você não apenas lê, mas USA. Isso é válido pra tudo, não só pra OpenSSL e criptografia. Quer aprender a programar ? Idealize um programa simples e faça-o. Cada parte do programa vai exigir que você pesquise como fazer, e somente o uso disso vai te trazer experiência, não apenas conhecimento.

Conclusão

Com esta série de posts, eu acho que já temos uma introdução bem “consistente” sobre esse assunto, a partir de agora vamos ver nos próximos posts o que mais temos no AdvPL onde isso pode ser usado, e como usar !!!

Agradeço a todos pela audiência, e lhes desejo TERABYTES DE SUCESSO !!!

Referências

 

Criptografia em AdvPL – Parte 10

Introdução

No post anterior, vimos em mais detalhes o objetivo e uso das chaves públicas, e como funciona um Handshake de conexão segura para HTTPS. Agora, vamos ver como gerar um certificado digital a partir de outro certificado, usando o certificado “pai” para autenticar o certificado “filho”, e usar isso no nosso exemplo de HTTPS 😀

Posts anteriores

Lembrando do primeiro teste com HTTPS

No Post 06 tem a receita de bolo pra gerar um certificado auto-assinado e usá-lo no TOTVS Application Server para prover acesso via HTTPS. Em resumo, trata-se de um certificado auto-assinado com extensões v3, para ser usado no servidor HTTPS em um determinado host, e para o navegador aceitar o certificado, ele precisava ser instalado na máquina cliente como um Trusted Root Certificate.

Certificados com cadeia de autenticação

Agora, vamos fazer um mecanismo um pouco mais elegante: Criar um certificado raiz auto-assinado, e criar um outro certificado para o HTTPS, com todos os dados necessários, porém assinado pelo primeiro certificado. E isso permite eu praticamente fazer o papel de uma autoridade certificadora — não oficial, claro.

Imagine que eu vou fazer o papel fictício de Autoridade Certificadora, e você quer criar um site seu, usando um certificado seu, mas quer que ele seja autenticado pelo meu certificado. Eu, como autoridade certificadora fictícia, tenho um certificado auto-assinado que eu uso como “raiz”, a base de tudo, com uma chave privada minha atrelada a este certificado.

Então, primeiro você cria a sua chave privada para ser usada pelo seu certificado. Porém, você não vai criar o certificado propriamente dito, você vai criar uma CSR (Certificate Signing Request), ou requisição de assinatura de certificado, com tudo o que você quer no seu certificado, e vai mandar ela para eu assinar com o meu certificado e com a minha chave. Eu vou criar o seu certificado para você, usando os dados que você forneceu na requisição de assinatura, e vou assinar o seu certificado com o meu.

Repare que eu tenho uma chave privada do meu certificado, e você vai usar a sua chave privada no seu certificado, mas em nenhum momento nem eu e nem você podemos tre acesso as chaves privadas um do outro. Neste processo as chaves públicas são intrinsecamente utilizadas: Quando eu receber a sua requisição de assinatura, a requisição em si traz junto a sua chave pública embutida, e todos os dados que você quer no seu certificado. Eu crio e assino o seu certificado, para que ele possa ser autenticado pelo meu certificado, mas o seu certificado ainda assim vai usar a sua chave privada no seu ambiente.

Quando você colocar o seu site no ar, você vai usar o seu certificado e a sua chave privada nas configurações do HTTPS, porém você não vai precisar pedir para os seus clientes — que vão acessar o seu site — instalar o seu certificado na maquina deles, você pede para eles instalarem o meu certificado — que assinou o seu — como Trusted Root Certificate. 😀 Assim, a máquina que tiver o meu certificado raiz não vai ter a minha chave privada, e o meu certificado será usado para verificar a assinatura do seu certificado quando o cliente acessar o seu site 😀

Fazendo a mágica

Eu, atuando como Autoridade Certificadora, crio a minha chave privada e o meu certificado auto-assinado:

-- Criando chave privada protegida por senha 
openssl genrsa -des3 -out rootCA.key 4096

-- Criando o meu certificado raiz para ser uma "autoridade certificadora"
openssl req -x509 -new -nodes -key rootCA.key -sha256 -days 1024 -out rootCA.crt 

O primeiro comando vai perguntar a senha para uso da chave privada, e na criação do meu certificado raiz eu coloco informações que me identificam.

Agora você vai criar a sua chave privada e uma requisição de assinatura para o seu certificado:

-- Voce cria a sua chave privada
openssl genrsa -out mydomain.com.key 2048

-- e cria uma requisição de assinatura
openssl req -new -key mydomain.com.key -out mydomain.com.csr -subj "/C=BR/ST=SP/L=Sao Paulo/O=Testes INC/CN=mydomain.com" 

A sua requisição de assinatura vai estar gravada no arquivo “mydomain.com.csr“, e você manda esse aquivo para eu assinar com o meu certificado. Eu vou assinar seu certificado com o seguinte comando:

openssl x509 -req -in mydomain.com.csr -extfile v3.ext -CA rootCA.crt -CAkey rootCA.key -CAcreateserial -out mydomain.com.crt

Para assinar o seu certificado, eu tive que criar um arquivo a mais, no exemplo acima chamado de “v3.ext”, onde eu vou colocar algumas extensões no seu certificado.

basicConstraints = CA:FALSE
keyUsage=digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment
subjectKeyIdentifier = hash
subjectAltName=DNS:mydomain.com

No final das contas, o seu certificado vai ser gerado no arquivo “mydomain.com.crt“, e eu mando esse arquivo pra você, e mando também o meu certificado “rootCA.crt“.

Agora você tem a sua chave privada “mydomain.com.key”  e o seu certificado “mydomain.com.crt“, e você configura o seu servidor HTTPS para usá-los.

[sslconfigure]
CertificateServer=c:\Protheus12LG\certificates\mydomain.com.crt
KeyServer=c:\Protheus12LG\certificates\mydomain.com.key

E, você ou qualquer outra pessoa que acesse o seu site, deve apenas instalar o meu certificado na máquina cliente como “Trusted Root Certificate“. Dessa forma, quando um navegador abrir o seu site, ele vai encontrar o seu certificado, e para validar a relação de confiança desse certificado, ele procura um certificado raiz confiável, e encontra o meu certificado — que é capaz de dizer que o seu certificado foi assinado por mim 😀

Se, amanhã você colocar outro site no ar, você repete o processo de criação de chaves e requisição de assinatura, e eu crio e assino o seu novo certificado, e todas as pessoas que já instalaram o meu certificado nas máquinas delas para acessar o seu site, não precisam mais instalar nada, pois o meu certificado raiz é capaz de autenticar qualquer certificado que eu tenha assinado com ele 😀

Estendendo a cadeia de autenticação ou confiança

Por hora a cadeia de autenticação desse exemplo possui apenas o certificado raiz, e cada certificado assinado por ela confia no raiz. Se, ao invés de você me pedir para assinar um certificado de uso final, você crie o seu certificado raiz e eu assine esse certificado, você mesmo pode emitir certificados para terceiros, assinados com o seu certificado raiz. Com isso, quando um navegador usar um certificado que você emitiu, ele vai procurar o seu certificado raiz — que não necessariamente precisa ser um “Trusted Root”, mas sim um “Trusted CA” — e quando ele encontrar o seu certificado raiz, ele verifica que ele foi emitido por mim, e confia nele desde que o meu certificado raiz seja um “Trusted Root” 😀

Eu sei, logo de cara é um pouco complicado, mas esse mecanismo — quando bem configurado e utilizado — provê um mecanismo de confiança muito seguro. Vamos ver agora alguns exemplos do mundo real.

Assinatura digital de aplicativos

Quando você vai instalar um programa qualquer,  o sistema operacional da sua máquina verifica se o seu programa tem uma assinatura digital que indica quem é o fornecedor desse programa. A cadeia de autenticação é praticamente a mesma, porém você tem um tipo diferente de certificado, com outras propriedades e extensões. Na instalação do programa, ao verificar o certificado usado para a assinatura, caso a assinatura não possa ser verificada, o sistema operacional pergunta se você confia nessa assinatura, e você aceita o risco de instalar o programa. E, se você confia naquela assinatura, você pode ainda declarar que “sempre confia” naquela assinatura, e quando você instalar outro programa assinado com este certificado, o sistema operacional não vai perguntar novamente se você confia nele, e vai deixar o programa ser executado.

Agora, já pensou se alguém consegue assinar um aplicativo malicioso, com um vírus ou um Trojan Horse, copiando a assinatura da Microsoft ? Ou da Symantec ? Se a assinatura for determinada erroneamente como confiável, o estrago é inimaginável e transparente, o programa faz o que quiser com a sua maquina !!! Por isso a infraestrutura de segurança é desenhada para não ser quebrada, senão a “vaca vai pro brejo” !!!!

Conclusão

Já vimos bastante coisa até o momento, mas ainda têm bastante a ser visto. Toda essa introdução com os respectivos exemplos serve para a gente entender o tamanho do mecanismo e seus componentes. A partir de agora, todas as demais camadas e mecanismos são baseados em tudo o que foi explicado até aqui, isso serve de “base” para tudo o que ainda vamos ver pela frente !!!

Agradeço novamente pela audiência, e lhes desejo TERABYTES DE SUCESSO !!! 

Referências

 

 

Criptografia em AdvPL – Parte 09

Introdução

No post anterior — Post 08 — aproveitamos o certificado criado e configurado no Post 06 para configurar uma conexão segura entre o SmartClient e o TOTVS Application Server. Agora, vamos ver um pouco mais sobre o que são e onde as chaves públicas entram nessa brincadeira, e como isso pode ser usado.

Posts anteriores

Chaves públicas

Até agora vimos superficialmente uma receita de bolo de criação de certificados auto-assinados que foram usados para testes em HTTPS e Conexão Segura entre SmartClient e o TOTVS Application Server. Mas, até agora só vimos chaves privadas — os arquivos .key criados até o momento. Então, cadê a tal da chave pública ?!

Obtendo a chave pública a partir de uma chave privada

Quando geramos o certificado auto-assinado no Post 06, a chave privada foi gerada no arquivo “note-automan-ssd.key“. Para obter a chave pública a partir desta chave privada, podemos usar o comando abaixo:

openssl rsa -in note-juliow-ssd.key -pubout -out note-juliow-ssd-public.key

A chave pública será gerada  e salva no arquivo “note-juliow-ssd-public.key“.

Legal, e  que eu faço com isso ?

Bem, uma chave pública têm muitos usos … vou ilustrar um cenário prático de uso. Imagine que você quer mandar um arquivo confidencial de forma encriptada para um determinado destinatário, porém apenas esse destinatário pode ter acesso ao conteúdo do arquivo. Para isso ser possível e feito de forma segura. a pessoa que vai receber essa mensagem deve ter uma chave privada dela ou criada por ela, extrair a chave pública — a partir da chave privada dela — e lhe enviar a chave pública. A chave pública consegue codificar uma informação, mas apenas a chave privada consegue ler ou decodificar esta informação.

A forma mais elegante de fazer essa troca de arquivos é você criptografar o arquivo usando uma método criptográfico simétrico com uma senha bem forte, que inclusive pode ser gerada dinamicamente, e então você usa a chave pública do destinatário para encriptar o arquivo com a senha — assim você não precisa codificar o arquivo inteiro para o destinatário, mas apenas codificar o arquivo com a senha.

Então você manda o arquivo criptografado para o destinatário, e manda o arquivo com a senha que ele deve usar para abrir esse arquivo, criptografada usando a chave pública dele. Quando ele receber esses dois arquivos, ele primeiro precisa decodificar o arquivo com a senha usando a chave privada dele — que só ele tem acesso — para então descobrir a senha de criptografia do arquivo de dados e poder decodificá-lo.

E onde entra o certificado digital nisso ?

Então, uma parte da mágica do certificado digital é a seguinte: Quando você cria um certificado digital, você deve informar uma chave — privada — para ser usada na criação do certificado. Quando o certificado digital é criado, a chave púbica que faz par com a chave privada utilizada vai dentro do certificado 😀

Logo, para o passo de criptografia anterior, se o cidadão tem um certificado digital, ele pode enviar apenas o certificado dele, que já tem a chave pública dentro. Você apenas extrai a chave pública do certificado que ele te enviar, e usa ela. Assim, inclusive, você pode exigir que o seu destinatário lhe envie um certificado de identidade oficial — como  um eCPF ou eCNPJ — e você pode confirmar com quem você está compartilhando o seu arquivo confidencial 😀

Por exemplo, para obter a chave pública a partir do certificado “note-juliow-ssd.cer” — que criamos para o HTTPS — usando a OpenSSL, usamos o seguinte comando:

openssl x509 -in note-juliow-ssd.cer -pubkey -noout >note-juliow-ssd-public.key 

O comando acima vai obter a chave pública do certificado e salvá-la no arquivo “note-juliow-ssd-public.key“. 

Logo, se alguém conseguir “roubar” apenas o seu certificado, sem a chave privada não dá pra usar ele pra abrir nenhum conteúdo codificado.

Então, uma conexão HTTPS usa a chave pública do certificado do servidor para criptografar os dados ?

R: QUASE ISSO …

Calma, vou explicar … vamos abordar primeiro a conexão HTTPS que configuramos para teste. Ela é uma conexão segura de uma via de autenticação, isto é, ela garante a identidade do servidor no qual o cliente está se conectando. E, a criptografia assimétrica — usada nas chaves públicas e privadas — exige um poder computacional muito maior para serem utilizadas, o que inviabiliza usar ela para codificar as informações, logo as mensagens serão criptografadas na conexão usando um método de criptografia simétrica. Basicamente, o Handhake de uma conexão segura entre o cliente e o servidor com um certificado e chave privada deve permitir ao cliente verificar a autenticidade do certificado usado pelo servidor, e prover um meio de comunicação seguro e inviolável entre eles, de modo que apenas o servidor entenda o que o cliente está enviando, e somente o cliente entenda o que o servidor está devolvendo para ele.

Então, COMO ?!

A versão simples da ópera é a seguinte: Em uma conexão usando criptografia RSA, o cliente gera uma chave criptográfica aleatória de 48 bytes, chamado de pre-master secrete criptografa essa chave usando a chave pública do certificado do servidor. O servidor recebe essa chave e decodifica usando a chave privada dele. Logo depois disso, como as duas pontas — cliente e servidor — tem o pre-master secret, agora ambos vão gerar uma nova chave — chamada master secret, baseada no pre-master secret, e ambos passam a usar essa nova chave para a criptografia simétrica das mensagens entre eles. E, para ter certeza que ambos estão “de acordo”, eles trocam uma mensagem adicional codificada com o algoritmo negociado, e quando ambas as partes finalizam o Handshake, a conexão está segura e pronta para  uso !

Assim, cada conexão de um novo cliente no mesmo servidor cria uma chave simétrica diferente e exclusiva para a conexão entre eles, que só eles sabem como foi gerada. Por isso que, mesmo que você consiga rastrear o inicio de uma conexão HTTPS em uma rede, a chave simétrica “base” da conexão foi gerada pelo cliente, e enviada criptografada para o servidor, e só ele sabe o que tem dentro, e sobre ela foi gerada uma chave mais forte ainda … e mesmo que os dados desde então sejam criptografados com uma chave simétrica, ela é única para esta conexão, e grande demais para ser quebrada.

Conclusão

Em 1976, Whitfield Diffie e Martin Hellman publicaram um estudo científico chamado “New Directions in Cryptography“, introduzindo uma forma radicalmente nova de troca de chaves criptográficas, que ajudaram a resolver um problema fundamental da criptografia. O método de troca de chaves criptográficas ficou conhecido como Diffie–Hellman key exchange, e a criptografia digital que usamos hoje é baseada nisso 😀

Espero que este conhecimento lhe seja tão proveitoso quanto a minha satisfação em compartilhá-lo, e desejo novamente a todos TERABYTES DE SUCESSO !!!

Referências

 

 

Criptografia em AdvPL – Parte 08

Introdução

No post anterior, vimos alguns pacotes de rede e requisições feitas com HTTP e com HTTPS, e um FAQ com algumas perguntas intrigantes e respectivas respostas. Agora, vamos aproveitar que já temos um certificado digital de testes e habilitar a conexão segura entre o TOTVS SmartClient e o TOTVS Application Server ?!

Posts anteriores

Conexão SmartClient com SSL

A seção de configuração [sslconfigure] do TOTVS Application Server foi criada para definir as configurações default para uso de criptografia na infraestrutura do servidor de aplicação, e auxiliar na portabilidade de funções nativas da linguagem para suporte a protocolos seguros. Ela possui diversas chaves de configuração, o que vimos até agora no post 06 foi apenas configurar o uso de um certificado digital e uma chave criptográfica em modo “servidor”, utilizada pela engine de servidor WEB nativa da plataforma para publicar um site ou serviço acessado por HTTPS.

Porém, também podemos habilitar uma conexão segura e criptografada entre o SmartClient e o Application Server, e quando fazemos isso, o certificado configurado como “ServerCertificate” e a sua chave correspondente serão usados para permitir essa implementação.

Configuração DRIVERS

No arquivo de configuração do TOTVS Application Server (appserver.ini), existe uma seção chamada [drivers], responsável por indicar a seção TCP para especificar a porta de conexão a ser usada pelo TOTVS SmartClient, Monitor, IDE/TDS e afins. Para habilitar a conexão segura para o SmartClient, acrescentamos as chaves em negrito:

[drivers]
active=tcp
secure=ssl

[tcp]
type=tcpip
port=12010

[ssl]
type=tcpip
port=13010

Pronto, com isso o Application Server vai usar a porta 13010 para atender a conexões seguras de SmartClient. Lembre-se que o certificado digital e a chave deve estar configurados na seção SSLConfigure, senão o Application Server não inicia…

[sslconfigure]
CertificateServer=C:\Protheus12LG\certificates\note-juliow-ssd.cer
KeyServer=C:\Protheus12LG\certificates\note-juliow-ssd.key

Para as conexões do SmartClient, pode ser usado o mesmo certificado que foi gerado para o HTTPS, inclusive pode até ser um certificado mais “simples”, sem as extensões obrigatórias que um navegador Web exige.

E uma vez feito isso e reiniciado o Application Server, você não precisa fazer nada nas configurações do SmartClient. O Application Server continua aceitando as conexões do SmartClient na porta da seção TCP, porém ao receber uma conexão de SmartClient na porta não segura, o próprio Application Server sabe que existe uma porta segura de conexão, então ele devolve para o SmartClient uma mensagem de reconexão segura, informando a porta configurada na seção SSL 😀

Quando o Application Server com estas configurações for iniciado, repare que no log de console devem aparecer algumas novas mensagens:

Secure Application Server.

[ERROR][STORE] Certificates loaded from [C:\Protheus12LG\certificates\note-juliow-ssd.cer].
[INFO ][SERVER] [Thread 11048] Secure Server started on port 13010.

The callback state information is active.
The PassPhrase is supplied.

*** Existe uma mensagem informando “ERROR” no log acima, que provavelmente está equivocada, deveria ser “INFO” — pois o certificado foi carregado com sucesso.

Configurando o SmartClient para conectar direto na porta segura

Embora apenas a configuração do Application Server já resolve a questão de conexão segura, existe uma forma de você configurar o SmartClient para conectar direto na porta segura, assim o SmartClient não precisa conectar na porta não segura para receber o número da porta segura e reconectar. Basta editar o arquivo de configuração do SmartClient (smartclient.ini), e criar uma nova seção de configuração de conexão, informando na seção a porta segura, e acrescentando a configuração SecureConnection=1, por exemplo:

[drivers]
active=tcp

[tcp]
server=note-juliow-ssd
port=12010

[ssltest]
server=note-juliow-ssd
port=13010
SecureConnection=1

Ao executar o SmartClient, basta trocar a conexão tcp para ssltest, e ele conectará direto na porta de conexão segura especificada, veja imagem abaixo:

Smartclient_ssl

Informações adicionais de depuração de SSL

Caso exista algum problema com uso de certificado ou criptografia no TOTVS Application Server, em qualquer funcionalidade que use chaves criptográficas e certificados e afins, é possível colocar na seção [sslconfigure] a chave verbose=1 . Com isso qualquer processo que envolver a camada de segurança e criptografia do Application Server vai gerar mensagens adicionais de diagnóstico no log de console do servidor. Vale lembrar que isso deve ser ligado apenas para fins de depuração, pois ela pode gerar muito conteúdo adicional e os detalhes gerados são apenas úteis para levantar mais informações sobre um problema relacionado a este mecanismo.

A seção [sslconfigure] possui muito mais chaves, se você está curioso em saber todas elas, veja os links de referência no final do post para a documentação oficial do TDN. Cada post explorando um novo recurso ou funcionalidade vai abordar sob demanda as chaves necessárias e explicando mais detalhes do seu funcionamento 😀

Conclusão

Com o que vimos até agora, já foi possível testar conexões seguras de HTTPS e SmartClient. No próximo post, vamos ver um pouco mais sobre os certificados digitais, e onde as funções do AdvPL se encaixam no uso desses certificados para diversos fins.

Agradeço novamente pela audiência, e desejo a todos TERABYTES DE SUCESSO !!! 

Referências

 

Criptografia em AdvPL – Parte 07

Introdução

No post anterior, configuramos um TOTVS Application Server como servidor HTTP e HTTPS, usando um certificado digital criado na raça usando a OpenSSL, do tipo “auto-assinado”, sem uma Autoridade Certificadora. Agora, aproveitando que temos um ambiente com um site que atende conexões não-seguras e seguras, vamos ver o que passa por dentro da camada de rede usando esses dois tipos de conexão.

Posts anteriores

Usando um analisador de pacotes de rede

Como temos agora um servidor configurado para conexões HTTP (Porta TCP 80) e HTTPS (Porta TCP 443), vamos ver como é possível “interceptar” a comunicação entre o navegador e o servidor HTTP usando um programa “espião de pacotes” — também chamados de Sniffer ou Network Packets Analyzer.

No caso, vou usar um analisador de rede chamado Wireshark — OpenSource, já tem Builds prontas para Windows e Linux, disponíveis no link https://www.wireshark.org/download.html — A instalação é tão simples quanto Next->I Agree->Next->Next->Next->Finish. Não vou entrar em mais detalhes desse recurso no momento, não é o foco desse post, apenas vou mostrar como o conteúdo transferido entre o servidor HTTP e o navegador pode ser visto — este é o pacote de resposta do servidor com a página HTML, usando uma conexão HTTP (não segura):

wireshark_http.png

A requisição que a imagem acima mostra é a resposta do servidor HTTP quando eu abri o navegador e pedi a página http://note-juliow-ssd.index.html. Se a gente ver o quando de informações o navegador enviou para o servidor quando pediu essa página, o Browser manda muitas informações:

GET /index.html HTTP/1.1
Host: note-juliow-ssd
Connection: keep-alive
Pragma: no-cache
Cache-Control: no-cache
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.100 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3
Accept-Encoding: gzip, deflate
Accept-Language: pt-BR,pt;q=0.9,en-US;q=0.8,en;q=0.7,es;q=0.6,sv;q=0.5

As informações acima foram enviadas pelo Chrome ao servidor HTTP do Protheus quando eu pedi um “Refresh” da página Index.html.

Interceptando os pacotes de uma conexão segura

Bem, meu chapa, o analisador de pacotes de rede intercepta tudo, inclusive uma conexão segura … Você consegue ver todas as etapas de HandShake e trocas de cifras e certificados entre as partes envolvidas, e depois os pacotes de dados … mas não adianta NADA, mesmo que você intercepte TODOS os pacotes … os tipos de informações trocadas entre o navegador e o servidor também estão criptografadas, o máximo que você pode fazer é olhar para os pacotes de dados e chorar … por que somente o servidor e o navegador sabem o que tem dentro 😀

https_application_data

Por exemplo, na imagem acima vemos um dos pacotes de dados trocados entre o navegador e o servidor HTTPS … não dá pra saber se foi uma pergunta ou uma resposta, ou o que isso quer dizer … e mesmo que você consiga fazer um ataque conhecido como “Man In The Middle”, isto é, fazer esta conexão passar por um “Tunnel TCP” dentro de uma aplicação sua, se você tentar mexer em um bit desse conteúdo, a decodificação da mensagem falha e a requisição sequer será processada, a camada de segurança que encapsula a conexão retorna um erro, e tchau.

Todo esse mecanismo tem como base a chave criptográfica privada armazenada no arquivo  “note-juliow-ssd.key”, em formato codificado BASE64. Como esta chave é única, e ainda foi criada sem senha, se eu usar ela para uma comunicação segura de uma aplicação de comunicação oficial, eu já comecei errado, por várias razões.

  • Chave privada sem proteção de senha
  • Certificado emitido sem uma Autoridade Certificadora

Se alguém coloca a mão nessa chave privada, desprotegida, e ela é usada para trocas de dados importantes, é possível gerar um outro certificado com outros dados baseado nesta chave, e usá-lo por exemplo para subir um servidor que finge ser “eu” em outro endereço na internet. e usando outros artifícios, fazer um “Tunnel TCP” entre o cliente e o meu servidor verdadeiro, capaz de ver o conteúdo descriptografado das mensagens — inclusive eu pretendo fazer esse teste mais pra frente.

E, se eu perder a minha chave privada, ou ela está protegida por senha e eu esquecer a senha … e eu usei essa chave para criptografar documentos, arquivos, imagens, qualquer coisa, esquece. Sem ela nem eu consigo decodificar as informações. Por isso que foram criados até dispositivos de hardware — como o HSM — para o acesso e uso controlado e restrito destas chaves. A segurança dessas chaves é criada de tal forma, que é possível saber que a senha está errada, mas não é possível determinar a senha certa.

F.A.Q.

P: O certificado foi gerado para o host  “note-juliow-ssd”, o que acontece se eu tentar acessar o HTTPS usando por exemplo https://localhost/index.html ou o IP da máquina ?

R: Como o certificado possui uma definição de DNS usando “note-automan-ssd“, se eu usar outro hostname para abrir o site, o Navegador avisa que tem algo errado — mais precisamente o erro “NET::ERR_CERT_COMMON_NAME_INVALID”

https_failed

P: Tentei abrir o endereço certinho no Mozzila, mesmo depois de importar o certificado. Por que não funcionou ?

mozilla_failedR: Repare na mensagem de erro :  MOZILLA_PKIX_ERROR_SELF_SIGNED_CERT — O navegador Mozilla é mais restritivo, mesmo eu importando o certificado, ele avisa que trata-se de um certificado auto-assinado, mas permite continuar desde que você clique no link “Aceite o risco e continue” 😛 

P: Se eu entrar no site do Google por exemplo, digitando http://www.google.com , aparece um cadeado ?! Como ?! Eu não entrei no site com uma conexão não-segura ???

R: Sim, você entrou, o site do Google, Facebook e muitos outros possuem o acesso por HTTP (Porta 80 sem criptografia) e HTTPS (Porta 443 com criptografia). Mas, quando você entra pela conexão não segura, o site atende a conexão com HTTP, e retorna uma instrução de redirecionamento para o navegador solicitar novamente a mesma URL, porém mas usando a conexão segura. Veja por exemplo o pacote retornado pelo Google quando eu abri uma URL de pesquisa usando http://www.google.com.br/search?q=siga0984

HTTP/1.1 307 Internal Redirect
Location: https://www.google.com.br/search?q=siga0984
Non-Authoritative-Reason: HSTS

P: Como uma conexão HTTPS de um site qualquer é segura, se eu não precisei instalar na minha máquina nenhum certificado para ela funcionar ?!

R: Uma conexão segura de HTTPS exige que pelo menos uma das extremidades tenha um certificado e uma chave. No caso, os sites “abertos” como Facebook , Google e a grande maioria, usam um certificado oficial apenas no servidor, para garantir a identidade do servidor, e a chave de criptografia para codificar a conexão. O navegador acessa o certificado do servidor no “HandShake“, e com isso pode confirmar que o site que você acessou é “oficial”. Alguns sites, como os da Receita Federal, podem exigir uma autenticação por cerificado digital, como um eCPF ou eCNPJ por exemplo, que você vai usar na sua máquina, para o site conseguir determinar quem é você 😀 Não é apenas uma conexão segura e codificada, mas também permite ao servidor saber mediante o seu certificado digital quem é você, e que “você é mesmo você” 😀

Conclusão

O que vimos nestes dois últimos posts foi apenas o be-a-bá de como subir um site de testes com HTTPS. Nos próximos posts, vamos desbravar mais possibilidades desse universo.

Espero que vocês aproveitem bem e usem com sabedoria e responsabilidade estes conhecimentos, e desejo a todos como sempre TERABYTES DE SUCESSO !!! 

Referências

 

Criptografia em AdvPL – Parte 06

Introdução

No post anterior, vimos o procedimento passo a passo para instalar a biblioteca de ferramentas OpenSSL 1.1.1c no Windows. Agora, vamos abordar o primeiro caso de uso: Como gerar um certificado digital para testes do TOTVS Application Server como um servidor HTTP com conexão segura (HTTPS) 😀

Posts anteriores

O que é HTTP e HTTPS ?

Bem, HTTP é o protocolo de comunicação criado sobre uma conexão TCP/IP, usado entre os navegadores de internet (ou Web Browsers) e sites que você acessa. O protocolo HTTP permite a transferência de vários tipos de conteúdos, desde páginas HTML estáticas, imagens, vídeos , arquivos, páginas dinâmicas, etc… Os dados podem ser trafegados em diversas codificações, inclusive compactados. Mas o HTTP usa uma conexão TCP “simples”, não segura. Desse modo, existem utilitários que permitem “farejar” conexões de rede (Sniffers) que podem interceptar e ver os conteúdos dos pacotes de dados trocados entre o navegador de Internet que você usa e o site que você está acessando.

Quando você acessa  um site que pode prover uma conexão segura, criptografada, o protocolo HTTPS é utilizado — o sufixo “S” significa “Secured”. A conexão segura é feita sobre SSL/TLS, onde no início da conexão existe uma etapa chamada de “Handshake” (aperto de mãos) entre o navegador e o servidor do site, onde eles literalmente “negociam” uma conexão criptografada — vamos ver mais pra frente os detalhes dessa negociação.

Uma vez estabelecida a conexão segura, os dados transferidos entre o navegador e o site são apenas encapsulados em pacotes codificados — criptografados –, mas ao serem decodificados, as mensagens trocadas estão no padrão HTTP. Apenas o meio de comunicação faz a ponte segura entre ambos.

TOTVS Application Server como servidor HTTP

Nos posts abaixo, eu explico como configurar o TOTVS Application Server como um servidor HTTP, recomendo essa leitura antes de prosseguir:

Refrescou a memória ? Legal, vamos partir da configuração inicial do TOTVS Application Server como um servidor HTTP de páginas estáticas, e criar a configuração para ele também aceitar conexões seguras. O Arquivo de configuração appserver.ini deve ficar assim:

[http]
enable=1
port=80
path=c:\Protheus12LG\Http\note-juliow-ssd

[https]
enable=1
port=443
path=c:\Protheus12LG\Http\note-juliow-ssd

Dessa forma eu configuro o Application Server para ser, ao mesmo tempo, servidor para conexões HTTP (não seguras) e HTTPS (seguras). As portas default usada para conexões HTTP e HTTPS são 80 e 443, respectivamente.

Dentro da pasta c:\Protheus12LG\Http\note-juliow-ssd, eu vou colocar apenas um arquivo, chamado index.html. Trata-se de um arquivo texto simples, que pode ser criado com o Bloco de Notas do Windows, apenas com o seguinte conteúdo para teste:

<html>
<body>
<h1><center>Olá Mundo HTTP do Protheus
</h1></center>
</body>
</html>

Agora, quando você tenta subir o TOTVS Application Server em modo console ou serviço … ele não sobe 😀 Aparece a tela de console, e desaparece rapidinho … quando abrimos o log de console ( console.log ) do servidor, encontramos as seguintes mensagens:

[INFO ][SERVER] [Thread 17340] HTTP Server started on port 80.

Http server is ready.
Root path is c:\protheus12lg\http\note-juliow-ssd\
Listening port 80 (default)

[INFO ][SSL] [tSSLSocketAPI][Initialize] Initializing SSL/TLS.
[ERROR][SSL] [tSSLSocketAPI][Initialize] There is no configuration of SSL certificates for the server.
[FATAL][SERVER] [14/08/2019 19:54:29][Thread 17340] *** HTTPS SERVER FAILED TO START ***

[INFO ][SERVER] [Thread 17340][14/08/2019 19:54:29] Application SHUTDOWN in progress...

Bem, como eu configurei o TOTVS Application Server para ser um servidor de conexões seguras para HTTPS, eu preciso ter um certificado digital configurado para isso. Bem, como o HTTPS ainda não sobe, altere para 0 o valor da configuração Enable da seção [https], e tente iniciar novamente o TOTVS Application Server.

[INFO ][SERVER] [Thread 1092] HTTP Server started on port 80.

Http server is ready.
Root path is c:\protheus12lg\http\note-juliow-ssd\
Listening port 80 (default)

Ótimo, agora parou “de pé” 😀 Vamos testar o acesso para ver a página Index.html no Browser. Você pode usar o nome do seu computador na URL do browse. Se você não lembra ou não sabe o nome do seu computador na rede, utilize o prompt de comando (cmd.exe) e digite echo %COMPUTERNAME%:

c:\>echo %COMPUTERNAME%
NOTE-JULIOW-SSD

No caso foi mostrado o nome do meu notebook. Agora, abrimos qualquer navegador (Chrome, Firefox, Internet Explorer, Opera ,…) e montamos uma URL com “http://&#8221; + o nome do computador+’/index.html’. No meu caso, http://note-juliow-ssd/index.html , e vejamos abaixo o que deve aparecer no Browse:

ola mundo http

Eu abri a URL usando o Google Chrome … reparem no texto circulado em vermelho: “Não seguro”. O navegador avisa que a conexão estabelecida não é “segura” — isso indica que a conexão atual não usa criptografia.

Como implementar e fazer funcionar o HTTPS ?!

Então, voltando pra conexão segura, temos basicamente duas etapas para conseguir habilitar o HTTPS no TOTVS Application Server:

  • Arrumar um certificado digital
  • Configurar o certificado para o Protheus usar.

Inicialmente, um certificado digital “oficial” para um servidor HTTP deve ser gerado por uma Autoridade Certificadora (ou CA – Certification Authority ). Entre as autoridades certificadoras brasileiras estão a Certisign, Serasa Experian e outras — para a lista completa veia o link https://www.iti.gov.br/icp-brasil/estrutura

Basicamente um certificado oficial deve possuir uma cadeia de autenticação — são certificados intermediários usados pelos navegadores para confirmar a autenticidade do certificado digital em uso pelo servidor HTTPS. Como não vamos publicar um site oficial, mas sim um teste de conexão segura, vamos a nossa primeira missão usando a OPENSSL: Criar um certificado digital auto-assinado 😀

Este tipo de certificado pode ser gerado por você mesmo, e da forma que ele é gerado, ele mesmo “se autentica” — na prática, é como eu criar um certificado digital com o os dados e propriedades que eu mesmo preencho, e eu mesmo digo que “esse certificado é de verdade” 😀

Criando um certificado auto-assinado para testes usando OPENSSL

Primeiramente, apenas em caráter informativo … Eu apanhei que nem “gato no saco” até chegar a uma receita de bolo que fizesse o navegador aceitar o certificado. As informações mais importantes são as seguintes:

  • O certificado requer parâmetros adicionais — chamados de “extensões” — para que o navegador entendesse que o certificado era para um site com o nome da minha máquina — note-juliow-ssd
  • O navegador de internet, por questões de segurança, verifica se o certificado possui uma Autoridade Certificadora válida, que não seja “eu mesmo”. Logo, a única forma de eu fazer o navegador ‘confiar” no meu certificado foi importar ele pelo gerenciador de certificados do próprio navegador — no meu caso o Chrome — como um “Trusted Root Certificate Authority”.

Agora, vamos para a receita de bolo — lembre-se que é necessário ter a ferramenta OPENSSL instalada para gerar a chave e o certificado. E, para o certificado que você gerar funcionar no seu computador, lembre-se de trocar note-automan-ssd para o nome do host do seu equipamento, e seguir os passos abaixo:

Passo 1:

Crie uma pasta no seu computador para guardar a chave e o certificado a serem gerado e utilizados, por exemplo c:\Protheus12LG\certificates

Passo 2:

Na instalação da OPENSSL, foi criada uma variável de ambiente apontando para o arquivo de configuração da openssl — no meu caso, “C:\Program Files\OpenSSL-Win64\bin\openssl.cfg”. Confirme o aquivo de configuração usado na sua instalação, execute o seu editor de textos ( notepad ou notepad++ por exemplo) em Modo “Administrador” — senão você não consegue mexer nesse arquivo — e abra o arquivo de configuração no editor, vá no final do arquivo, e acrescente o conteúdo abaixo:

[ v3_self_signed ]

authorityKeyIdentifier=keyid,issuer
basicConstraints=CA:FALSE
keyUsage=digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment
subjectAltName=DNS:note-juliow-ssd

Com isso, eu criei uma seção de configuração nova para colocar no meu certificado os dados necessários para o Browse entender que eu vou usar esse certificado para conexão segura em um site de testes na minha máquina ( note-juliow-ssd ). Salve o arquivo e feche o editor.

Esse passo aqui é que deu trabalho descobrir — sem ele, mesmo que eu importasse o certificado como “confiável”, o Chrome retornava o erro “ERR_CERT_INVALID_COMMON_NAME”, como se o certificado não tivesse as informações corretas para ser usado em um site usando o nome da minha maquina … 

Passo 3:

Abra um prompt de comando (cmd.exe) no Windows, entre na pasta onde você vai gerar o certificado digital e a chave privada do certificado, e execute o comando abaixo:

openssl req -x509 -nodes -newkey rsa:4096 -keyout note-juliow-ssd.key -out note-juliow-ssd.cer -days 365 -subj “/C=BR/ST=SP/L=Sao Paulo/O=Tudo em AdvPL/CN=note-juliow-ssd” -extensions v3_self_signed -reqexts v3_self_signed

Com esse pequeno monstrinho, em apenas uma etapa eu consigo fazer a OpenSSL criar para mim uma chave privada de 4096 bits, usando criptografia RSA, gravar a chave SEM SENHA no arquivo note-juliow-ssd.key, criar um certificado no padrão x509 usando esta chave, com validade de um ano, colocando alguns dos meus dados no certificado, e acrescentando as extensões necessárias que colocamos no passo 2 na configuração da OpenSSL, salvando o certificado criado no arquivo note-juliow-ssd.cer

Agora vamos ver o resultado:

C:\>cd Protheus12LG\certificates

C:\Protheus12LG\certificates>openssl req -x509 -nodes -newkey rsa:4096 -keyout note-juliow-ssd.key -out note-juliow-ssd.cer -days 365 -subj "/C=BR/ST=SP/L=Sao Paulo/O=Tudo em AdvPL/CN=note-juliow-ssd" -extensions v3_self_signed -reqexts v3_self_signed
Generating a RSA private key
.......................................................................................................++++
..........................++++
writing new private key to 'note-juliow-ssd.key'
-----

C:\Protheus12LG\certificates>

Para conferir o conteúdo do certificado que foi gerado, executamos o seguinte comando:

openssl x509 -text -in note-juliow-ssd.cer -noout

E, abaixo vamos ver o que foi retornado:

Certificate:
Data:
Version: 3 (0x2)
Serial Number:
5e:a9:76:38:db:c0:3c:5e:cf:f6:8b:e0:cf:7c:b8:5c:ad:87:59:d9
Signature Algorithm: sha256WithRSAEncryption
Issuer: C = BR, ST = SP, L = Sao Paulo, O = Tudo em AdvPL, CN = note-juliow-ssd
Validity
Not Before: Aug 16 00:06:19 2019 GMT
Not After : Aug 15 00:06:19 2020 GMT
Subject: C = BR, ST = SP, L = Sao Paulo, O = Tudo em AdvPL, CN = note-juliow-ssd
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
RSA Public-Key: (4096 bit)
Modulus:
00:bc:5b:56:04:e2:8a:58:88:65:22:86:ce:33:42:
c4:15:1a:ca:9b:4e:ad:7e:7b:42:92:7e:64:e9:3b:
5c:30:f9:de:34:b0:c3:fb:e2:62:69:e7:d7:3c:f1:
cb:78:c2:84:da:15:c3:2b:22:2c:30:7d:71:3f:d4:
47:34:0a:39:50:d4:8f:bc:fa:17:0b:ee:6e:38:28:
1a:06:b3:38:82:51:64:bf:7b:d0:75:ea:fd:e1:f9:
85:ac:21:fa:f8:ee:fb:b5:79:6a:02:f5:83:15:fa:
95:b5:18:1f:76:e7:57:41:a1:f7:84:23:bd:8c:31:
ee:02:c6:58:43:6a:40:ff:24:41:b6:33:ce:eb:7b:
ad:14:d0:43:cf:bf:75:ec:6d:5a:be:94:83:6e:d7:
71:ec:40:b8:68:36:c8:2a:90:9c:d0:6e:64:9c:e6:
3e:28:6e:c5:3b:70:a4:c5:7d:ff:91:0d:f8:f2:f7:
27:dd:cd:04:06:2c:3a:ce:78:23:d3:43:2f:49:77:
e5:4e:13:2d:18:8c:43:5d:2e:7d:70:c4:db:5f:dc:
9a:b1:e6:05:37:14:f8:82:8a:5a:0c:47:22:07:ab:
61:20:43:83:b5:cc:8f:09:93:5f:b4:32:9b:19:b9:
50:35:91:2b:bb:8b:f7:5c:a6:7b:1e:29:b4:73:0d:
f8:93:e9:d6:9a:90:f8:49:a4:ab:89:8a:56:9f:8f:
6b:e1:7b:64:b4:aa:f8:11:6b:b9:92:66:aa:46:04:
5d:bb:5d:17:52:e1:17:36:86:80:70:1f:64:45:47:
6f:12:f2:cb:37:20:2b:6c:36:32:a7:ed:5a:9b:a9:
fa:47:34:a8:1a:79:8d:1d:84:e1:29:9e:a9:64:97:
f3:83:64:79:9e:9d:72:2a:05:0d:4e:58:ec:ff:2c:
d7:c5:a2:5c:b2:e6:08:26:8e:17:12:e3:99:2e:50:
7f:a6:3f:ef:6c:aa:45:08:0d:f8:db:fc:15:f4:42:
29:2d:13:d1:4c:2b:3e:72:1f:e9:0c:2a:bd:38:60:
5c:27:dd:63:7c:32:ac:c0:f0:06:85:1a:dc:64:67:
d9:44:bc:bc:83:fc:65:2a:1a:0c:04:77:ea:29:06:
f8:de:35:ba:4b:cd:23:c6:87:11:bf:4d:cc:d8:d0:
20:54:28:50:dd:b2:e3:21:f2:9d:67:1a:27:11:15:
6e:92:ac:3c:ac:66:70:86:31:bc:55:39:85:fe:9f:
65:02:29:d6:cc:36:51:f2:e2:15:93:13:6f:a1:b5:
47:af:cc:20:c7:94:fe:44:37:59:90:98:46:fd:be:
7a:1c:c1:87:7a:57:94:05:db:0a:60:f3:ca:42:1b:
01:89:35
Exponent: 65537 (0x10001)
X509v3 extensions:
X509v3 Authority Key Identifier:
DirName:/C=BR/ST=SP/L=Sao Paulo/O=Tudo em AdvPL/CN=note-juliow-ssd
serial:5E:A9:76:38:DB:C0:3C:5E:CF:F6:8B:E0:CF:7C:B8:5C:AD:87:59:D9

X509v3 Basic Constraints:
CA:FALSE
X509v3 Key Usage:
Digital Signature, Non Repudiation, Key Encipherment, Data Encipherment
X509v3 Subject Alternative Name:
DNS:note-juliow-ssd
Signature Algorithm: sha256WithRSAEncryption
78:55:d6:bf:57:6e:69:8b:c6:7e:27:7d:bc:e6:df:bc:17:26:
62:3b:73:e5:a5:46:51:6d:09:fa:45:c6:c3:6f:d3:9f:70:d3:
cb:2c:42:c8:48:fa:b5:ec:14:8a:d9:4c:c8:d9:eb:ab:bb:3a:
d7:35:e5:ad:88:90:1c:2d:91:ea:08:e1:87:f9:b8:dc:d4:d7:
58:77:8f:6b:b9:da:65:3c:e3:7a:fb:08:91:94:c4:43:08:53:
64:1f:ad:f9:93:66:bf:fa:58:af:25:a7:09:c8:f4:a9:77:fb:
4e:f5:33:02:f8:86:26:6e:f6:77:d1:7c:74:be:6d:09:4d:0e:
4a:38:44:08:bd:b8:a2:d3:85:c3:e7:a0:1d:81:57:3e:40:cc:
0e:08:8a:60:56:b7:c2:27:78:c1:6a:30:1e:58:ab:ab:44:a4:
9e:c6:7b:15:a9:e6:14:65:e0:b2:88:85:66:f1:cc:32:34:6b:
d9:a6:f5:e7:3d:5b:b5:a9:a8:a4:82:17:48:4e:f3:6d:26:80:
3c:72:66:23:c9:ee:d3:ed:0b:fe:0d:8d:04:b5:17:da:01:f4:
20:21:79:0f:18:7b:04:cd:c6:90:5f:a4:71:82:bd:90:d5:ce:
f0:c2:ea:1c:70:f7:5f:3c:d6:1c:cd:54:eb:7d:70:75:03:7c:
3f:49:02:3c:65:69:89:a2:c2:aa:9a:62:64:45:2f:e2:51:c2:
8f:d5:00:85:a1:e6:ec:48:4d:bb:5f:4f:09:73:4f:56:70:54:
04:0b:60:5f:2c:c0:cb:61:45:3b:5c:ff:cc:ac:67:9f:2a:67:
12:5e:38:16:af:b3:96:f1:24:2f:27:fe:63:9f:0b:d6:11:31:
08:7c:26:b9:2d:48:66:0b:b8:c3:4e:b3:0f:62:f7:79:17:0f:
a8:c7:fa:71:ad:40:7a:2c:92:a5:d8:5b:b9:ff:a5:4e:d7:88:
ad:59:ab:c4:1d:9b:ed:52:20:d0:20:70:dc:ed:09:03:f9:4e:
5d:5b:ed:51:86:74:d5:8d:62:ab:cc:5a:45:00:9d:28:d2:45:
bc:02:c1:c8:76:15:94:04:34:fe:68:69:52:72:68:13:31:ca:
6b:ac:17:0e:2c:3d:f0:4e:b8:ba:b3:48:f2:06:5b:e6:aa:be:
35:e8:81:48:78:14:3b:f6:48:eb:13:ef:bd:9b:3f:83:1c:4e:
24:be:b7:b8:c6:30:c0:00:cb:6c:74:50:3e:3d:84:d3:a5:ce:
fb:6e:ac:2c:62:eb:5f:96:d4:77:8a:46:e0:9f:6c:43:13:e9:
4f:09:3b:e1:9a:12:b6:35:83:19:8e:4b:59:78:a5:9f:cd:fc:
6d:ce:d6:53:fc:72:15:db

Se verificarmos o diretório atual, veremos que os dois arquivos — chave privada e certificado — foram criados. UFA … agora, vamos configurar o certificado e a chave privada para o Protheus utilizar e virar servidor HTTPS.

Passo 4:

Abra o arquivo de configurações do TOTVS Application Server ( appserver.ini ) , e acrescente o conteúdo abaixo:

[sslconfigure]
CertificateServer=C:\Protheus12LG\certificates\note-juliow-ssd.cer
KeyServer=C:\Protheus12LG\certificates\note-juliow-ssd.key

Com isso, eu informo ao Protheus que ele pode ser um servidor de conexão segura, usando o certificado e a chave privada informadas na configuração. Por hora é tudo o que precisamos saber e fazer pra mágica funcionar.

Aproveite que o arquivo de configuração está aberto, configure novamente a chave Enable=1 na seção [HTTPS] e salve o arquivo de configuração.

Passo 5: 

Inicie novamente o TOTVS Application Server. Se tudo estiver certo, agora ele tem que subir "certinho"

[INFO ][SERVER] [Thread 13104] HTTP Server started on port 80.

Http server is ready.
Root path is c:\protheus12lg\http\note-juliow-ssd\
Listening port 80 (default)

[ERROR][STORE] Certificates loaded from [C:\Protheus12LG\certificates\note-juliow-ssd.cer].
[INFO ][SERVER] [Thread 13104] HTTPS Server started on port 443.

Https server is ready.
Listening port 443 (default)

Passo 6: 

Abra o Chrome, e informe a URL de acesso da página de testes, mas agora usando HTTPS ao invés de HTTP

https://note-juliow-ssd/index.html

E, para nossa surpresa ….

chrome_cert_authority_invalid

O navegador de internet fez o “HandShake” com o HTTPS do Protheus, e viu que o certificado usado não tem uma Autoridade Certificadora válida. Logo, ele avisa que o site que você está acessando pode ser uma roubada …. Reparem no erro no meio da tela : ERR_CERT_AUTHORITY_INVALID. Como o certificado foi eu mesmo que gerei, e está na minha máquina, e é para testes, eu posso fazer o navegador “confiar cegamente” no meu certificado e funcionar redondinho sem mostrar mais essa mensagem.

Passo 7:

Vamos importar o certificado de testes utilizado para dentro do navegador, dizendo pra ele que este certificado é um “Trusted Root Certificate” — ATENÇÃO : PELO AMOR DE DEUS, NÃO FACA ISSO COM UM CERTIFICADO QUE NÃO FOI VOCÊ QUE GEROU OU QUE VOCÊ NÃO SABE A PROCEDÊNCIA. O certificado que a gente acabou de gerar é confiável por que você gerou ele e vai usar na sua máquina.

No Google Chrome, clique nos três pontinhos do canto superior direito da janela’e clique em “Configurações”. Ao abrir a janela de configurações, expanda a opção “Avançado”, e clique em “Privacidade e Segurança”, e depois em “Gerenciar Certificados”

chrome_avancado

Será mostrada a janela de controle de certificados. Localize e posicione na aba “Trusted Root Certification Authorities”, e depois no botão “Import”

chrome_certificates

Ao clicar em “Import”, será aberto um assistente de importação de cerificado digital:

chrome_import_1

Clique em “Next”, e na próxima tela informe o caminho completo do certificado a ser importado, ou use o botão “Browse” para localizar e selecionar o certificado que acabamos de criar.

chrome_import_2

Ao clicar em “Next” será mostrada uma tela para perguntar onde o certificado deve ser importado. Já vi vir preenchido com “Trusted Root Certification Authorities”, clique em “Next”.

chrome_import_3

Chegamos na última tela, o assistente mostra o resumo do que será feito. Clique em “Finish”.

chrome_import_4

Ao clicar em Finish, é mostrado um aviso de segurança, dizendo que você está para instalar uma Autoridade Certificadora que não pode ser verificada — por que não existe — e que diz representar o nome do host da sua máquina, e diz também que se você fizer isso, o Windows vai passar a confiar em qualquer certificado subsequente que seja emitido a partir desse. Pode confirmar 😀

chrome_import_5

Pronto! Insalado 😀

chrome_import_6

Passo 8:

Agora sim, abra novamente a página de testes com o protocolo seguro — pode ser necessário fechar e abrir novamente o navegador para o acesso funcionar. Tudo dando certo, devemos ver isso aqui:

chrome_agora_foi

Repare no “cadeado” destacado em vermelho. Isso informa que, agora sim, finalmente, estamos usando uma conexão SEGURA / CRIPTOGRAFADA. Agora, para ver os detalhes dessa criptografia do ponto de vista do browse, clique no cadeado:

chrome_valido

Vamos ver mais detalhes, clicando em cima da palavra  “Certificado”, e consultar as suas propriedades.

certificate_properties

Na aba de detalhes do certificado, podemos ver todas as propriedades que colocamos ao criá-lo, e como instalamos ele como um certificado confiável na máquina, o Windows agora confia nele 😀

Conclusão

Bem, com apenas esses “poucos passos” conseguimos montar um servidor de páginas HTTP com conexão segura … agora, no próximo post, vou mostrar o que um hacker consegue ver ao rastrear uma conexão não segura e uma conexão segura 😀

Agradeço a todos pela audiência, e lhes desejo TERABYTES DE SUCESSO !!!

Referências