Repository navigation
https cliente ral
Home > HTTPS > HTTPS no cliente
Vale para a 1.1 em diante · Delphi e Lazarus · Nível: intermediário
Em uma frase: o TRALClient pode aceitar só o certificado que você espera,
pela impressão digital, sem instalar nada na máquina nem no celular.
Servidor com certificado de CA pública (Let's Encrypt, pago)? Não precisa de nada desta página: funciona sozinho. Ela é para o autoassinado: servidor interno, acesso por IP, IP que muda, ou Android (que desde a versão 7 não confia em CA instalada pelo usuário).
| Membro | Para que serve |
|---|---|
SSL.Pins |
os certificados aceitos, e de qual servidor |
SSL.Required |
recusa http:// puro, diga o que disser a URL |
SSL.Verify |
o que o próprio motor faz com o certificado |
OnValidateServerCert |
decidir em código, quando a lista não basta |
Sem mexer em nenhuma, o cliente se comporta como sempre se comportou.
Do arquivo: openssl x509 -in cert.pem -noout -fingerprint -sha256
De um servidor no ar:
openssl s_client -connect 192.168.0.11:9988 </dev/null 2>/dev/null | openssl x509 -noout -fingerprint -sha256
Do certificado automático (2.0 🚧): a propriedade
Fingerprint.
Cole como vier: com :, espaços, minúsculas. O RAL normaliza. Valor que não é um
SHA-256 dá erro na hora de adicionar, não em produção.
Cliente.BaseURL.Text := 'https://192.168.0.11:9988';
Cliente.SSL.Pins.Add('6542DB04A4778A33BDBDF9EC5C953793D4F73572EA804C145FBB55641735290A');A partir daí: só aquele certificado é aceito (até um de CA é recusado); o nome e o
IP no certificado deixam de importar (trocar o IP não quebra); e http:// passa a
ser recusado para esse servidor.
Cada linha diz onde vale. Servidor que não tem linha é validado normalmente:
Cliente.SSL.Pins.Text :=
'192.168.0.11=CD34EF...'#13#10 + // só nesse host
'10.0.0.7:8443=90FFEE...'#13#10 + // nesse host e porta
'[2001:db8::1]:9988=1234AB...'; // IPv6 entre colchetes| Linha | Vale para |
|---|---|
impressão |
qualquer servidor |
host=impressão |
aquele host, qualquer porta |
host:porta=impressão |
aquele host e porta |
[ipv6]:porta=impressão |
IPv6 com porta |
Duas linhas para o mesmo servidor valem as duas. Distribua o cliente com a atual e a nova, troque o certificado no servidor quando quiser, e tire a antiga na versão seguinte.
Com o evento atribuído, só ele decide (nem pin nem motor):
function TForm1.ValidaCert(ASender: TObject; const ACert: TRALCertInfo): boolean;
begin
if ACert.Host = '192.168.0.11' then
Result := ACert.Fingerprint = PIN_INTERNO
else
Result := ACert.Trusted; // o resto: validação normal
end;TRALCertInfo traz Fingerprint, Subject, Issuer, NotBefore, NotAfter,
Trusted (o veredito do motor), Error, Host e Port (de quem você chamou).
Recusar corta a conexão antes de enviar qualquer byte, token incluído.
| Valor | Significa |
|---|---|
svEngine (padrão) |
o de sempre de cada motor: Indy e fpHTTP não conferem nada; netHTTP e mORMot2 conferem |
svAlways |
liga a conferência onde está desligada |
svNever |
aceita qualquer certificado. Só para teste |
svAlways no Windows com Indy ou fpHTTP recusa tudo, até CA pública, porque o
OpenSSL deles não tem lista de CAs lá. Prefira um pin.
| Motor | Confere por padrão | SSL.Pins |
OnValidateServerCert |
|---|---|---|---|
| Indy | não | sim | sim |
| fpHTTP | não | sim | sim |
| mORMot2 com OpenSSL | sim | sim | sim |
| mORMot2 no Windows (SChannel) | sim |
não: chame OpenSslInitialize (unit mormot.lib.openssl11) |
não |
| netHTTP | sim | só no Windows | sim (só pode vetar um certificado bom) |
OkHttp 1.2 🚧
|
sim | sim (Android) | sim |
MsQuic / Kwik 1.2 🚧
|
sim | sim | sim |
Pinar no Delphi e no Lazarus, no Windows e no Android, com uma configuração só:
Indy (com ssleay32.dll e libeay32.dll ao lado do programa).
Resposta.TransportError = rteCertificate (na chamada com evento). Nunca tenta a
próxima BaseURL por causa disso.
Com SSL.Required ou um pin para o servidor, um redirecionamento de https:// para
http:// não é seguido: a resposta 3xx volta como veio.
| Mensagem | Significa |
|---|---|
emCertRejected |
o pin ou o evento recusou |
emCertPinUnsupported |
aquele motor não lê impressão digital naquela plataforma |
emCertNotInspectable |
mORMot2 no SChannel: chame OpenSslInitialize
|
emCertPinInvalid |
linha de SSL.Pins mal escrita (avisa ao adicionar) |
emCertRequiresTLS |
SSL.Required ou pin, e a URL é http://
|
- O pin é mais forte que a validação por CA: só aquele certificado passa.
- Guarde a impressão no programa (constante), não num
.inieditável: quem edita a linha aponta o cliente para outro servidor. Host e porta podem ficar no.ini. - O pin não cifra nada sozinho: use HTTPS (
SSL.Required).
Manual completo (inglês): src/engine/SSL.md no repositório.
Começar
Servidor
- Rotas e parâmetros
- Ler o pedido e responder
- Plugins 🚧
- Autenticação
- Banco de dados (DBWare)
- Servir site e arquivos
- Swagger e Postman
- Servidor SOAP 🚧
- HTTPS
- Criptografia ponto a ponto
- Segurança para produção
- Colocar no ar
- Desempenho
Cliente
Motores
Avançado
Ajuda
- Problemas comuns
- Atualizar o Indy
- Várias versões do Delphi
- Vídeos e guias
- Módulos de terceiros
- Licenças
- Contribuir
- Roadmap e changelog
🚧 = em desenvolvimento, pode mudar