Repository navigation
criptografia curvas
Home > Curvas elípticas e AES-GCM 🚧
Important
Em desenvolvimento (2.0). Ainda não está numa versão lançada e pode mudar.
Vale para a 2.0 · Delphi XE em diante e Lazarus/FPC 3.2 em diante · Nível: avançado
Em uma frase: o pacote RALCryptoCurvesPackage traz X25519 (troca de chaves), Ed25519
(assinatura), HKDF (derivação de chaves) e AES-GCM (cifra autenticada), em Pascal puro, sem
OpenSSL nem DLL, para quem precisa dessas primitivas por conta própria.
Você vai precisar: o pacote RALCryptoCurvesPackage (sem componentes; só units), que requer o
PascalRAL. Não confunda com a criptografia ponto a ponto, que cifra o
corpo das requisições com AES-CBC.
- verificar a assinatura Ed25519 de webhooks (a Interactions do Discord assina cada chamada);
- assinar e conferir DKIM Ed25519 de e-mails;
- protocolos que combinam X25519, HKDF e AES-GCM, como o Noise usado pelo WhatsApp;
- cifrar com autenticação (quem altera o texto cifrado é detectado).
Todas trabalham com TBytes.
| rotina | |
|---|---|
RALX25519(escalar, ponto) |
o valor compartilhado (32 bytes) do seu escalar privado com o u do ponto do outro lado |
RALX25519Base(escalar) |
a chave pública do escalar (ponto base, u = 9) |
RALX25519GenerateKeyPair(priv, pub) |
gera um par a partir de 32 bytes aleatórios |
uses RALCurve25519, RALHKDF;
RALX25519GenerateKeyPair(PrivA, PubA);
RALX25519GenerateKeyPair(PrivB, PubB);
SegredoA := RALX25519(PrivA, PubB);
SegredoB := RALX25519(PrivB, PubA); // igual a SegredoA
if IsZero(SegredoA) then // ver "Limites"
raise Exception.Create('ponto inválido');
| rotina | |
|---|---|
RALEd25519PublicKey(semente) |
a chave pública (32 bytes) da semente (a chave privada, 32 bytes) |
RALEd25519Sign(mensagem, semente) |
a assinatura (64 bytes) |
RALEd25519Verify(mensagem, assinatura, chavePublica) |
True se a assinatura vale; recusa S >= L e pontos fora da curva |
RALEd25519GenerateKeyPair(semente, pub) |
gera o par |
uses RALEd25519;
// webhook: a chave pública, a assinatura e o carimbo vêm em hexa; o texto assinado é carimbo + corpo
if not RALEd25519Verify(Concat(Carimbo, Corpo), Assinatura, ChavePublica) then
AResponse.StatusCode := 401;
TRALHKDFHash escolhe o hash: rhkSHA256 ou rhkSHA512.
| rotina | |
|---|---|
RALHKDFExtract(hash, sal, material) |
o PRK; sal vazio vale uma sequência de zeros |
RALHKDFExpand(hash, prk, info, tamanho) |
tamanho bytes (no máximo 255 vezes o tamanho do resumo) |
RALHKDFDerive(hash, material, sal, info, tamanho) |
Extract e Expand juntos |
Chave := RALHKDFDerive(rhkSHA256, SegredoA, Sal, TEncoding.UTF8.GetBytes('minha-app v1'), 32);
| rotina | |
|---|---|
RALAESGCMEncrypt(chave, iv, aad, texto) |
o texto cifrado seguido da etiqueta de 16 bytes; chave de 16, 24 ou 32 bytes |
RALAESGCMDecrypt(chave, iv, aad, cifradoEtiqueta, texto) |
True e o texto, ou False e texto vazio quando a etiqueta não bate |
O aad é o que só se autentica (cabeçalhos, por exemplo) e pode ser vazio. O IV recomendado tem 12
bytes e nunca pode se repetir com a mesma chave. A etiqueta é comparada em tempo constante.
uses RALAESGCM;
Cifrado := RALAESGCMEncrypt(Chave, IV, nil, TEncoding.UTF8.GetBytes('olá'));
if RALAESGCMDecrypt(Chave, IV, nil, Cifrado, Texto) then
// Texto é o original; se alguém mexeu em Cifrado, o resultado é False
- O AES é por tabelas, e por isso não resiste a ataques de cache (timing) de quem roda código na mesma máquina. Serve para uma API em servidor próprio; não para código de terceiros executando ao lado do seu.
- X25519 com ponto de ordem pequena devolve só zeros. O RAL não recusa por você: confira o resultado e abandone a troca se ele for todo zero (RFC 7748, seção 6.1).
- Pascal puro é mais lento que o OpenSSL; para volume alto de dados, prefira a criptografia externa ou o motor com TLS.
- Chave privada e semente devem vir de bytes aleatórios do sistema;
GenerateKeyPairjá faz isso.
Começar
Servidor
- Rotas e parâmetros
- Rotas avançadas: tipos, grupos, versões 🚧
- Ler o pedido e responder
- Objetos no corpo 🚧
- Resposta em fluxo 🚧
- Plugins 🚧
- Autenticação
- Banco de dados (DBWare)
- Servir site e arquivos
- JSON-RPC 2.0 🚧
- Servidor MCP (IA) 🚧
-
Protocol Buffers 🚧
- gRPC 🚧
- WebSocket 🚧
- Hubs (WebSocket) 🚧
- Swagger e Postman
- Servidor SOAP 🚧
- WS-Security 🚧
- HTTPS
- Criptografia ponto a ponto
- Segurança para produção
- Colocar no ar
- Desempenho
- Testes em memória 🚧
MQTT 🚧
- O que é e quando usar 🚧
- Cliente MQTT 🚧
- Broker MQTT 🚧
- MQTT-SN 🚧
- Ponte REST 🚧
- Segurança 🚧
- Rede ruim 🚧
E-mail 🚧
Cliente
Motores
- Qual motor escolher?
- Compatibilidade
- Recursos
- QUIC
- Motor NgHttp2 (HTTP/2) 🚧
- Motor XSocket 🚧
- Motor AdvancedHTTP (experimental) 🚧
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