OpenPGP em Delphi: Criptografe, Assine e Verifique Sem o GnuPG

· Componentes
OpenPGP em Delphi: Criptografe, Assine e Verifique Sem o GnuPG

O OpenPGP ainda é a forma como muitas organizações trocam arquivos. Um banco quer lotes de pagamento criptografados com a sua chave pública, um parceiro envia relatórios criptografados com o GnuPG, uma release precisa ser distribuída com uma assinatura separada. Em Delphi, isso costumava significar instalar o GnuPG em cada máquina e chamar o gpg.exe por linha de comando, com todo o tratamento de caminhos, chaveiros e códigos de saída que isso traz.

O sgcCrypto agora implementa o OpenPGP por conta própria, em Object Pascal puro. Não há DLL para distribuir, nem ferramenta de linha de comando para chamar, nem dependência do Indy. Chaves, criptografia, descriptografia, assinaturas e verificação são um punhado de chamadas de função sobre TBytes, e o resultado interopera com o GnuPG nos dois sentidos.

Versão 4 e Versão 6

Duas gerações do formato são suportadas:

Ao criptografar para vários destinatários, a biblioteca escolhe o formato que todos conseguem ler: o formato AEAD da RFC 9580 quando todos o suportam, o formato clássico com proteção de integridade caso contrário. Uma mensagem para uma mistura de chaves antigas e novas abre em qualquer lugar.

Gere uma Chave

Uma chamada cria uma chave completa: uma chave primária de assinatura, uma subchave de criptografia, o ID de usuário e as autoassinaturas que os vinculam.

uses
  sgcCrypto_PGP, sgcCrypto_PGP_Cert;

var
  oAlice: TsgcPGPKey;
begin
  // v4 Ed25519 + Curve25519, the default key type of GnuPG
  oAlice := sgcPGP_GenerateKey('Alice <alice@example.com>', 'secret',
    pgpkEd25519, 4);
  try
    Memo1.Text := oAlice.SaveToArmored(False);  // public key, share it
    SaveSecretKey(oAlice.SaveToArmored(True));  // protected secret key
  finally
    oAlice.Free;
  end;
end;

Os tipos de chave são RSA 2048, 3072 e 4096, Ed25519, Ed448 (versão 6) e ECDSA com ECDH em NIST P-256, P-384 e P-521. Chaves Brainpool podem ser importadas. As chaves secretas são protegidas com a sua senha, usando SHA-256 iterado na versão 4 e Argon2 com AES-OCB na versão 6.

Criptografe e Descriptografe

Criptografe para uma ou mais chaves públicas, opcionalmente assinando como remetente. A saída é ASCII armored por padrão, pronta para anexar a um e-mail ou enviar a um servidor.

// encrypt to Bob, signed by Alice, compressed with ZIP
vEncrypted := sgcPGP_Encrypt(vData, [oBob], oAlice);

// or protect a file with a passphrase only
vEncrypted := sgcPGP_EncryptSymmetric(vData, 'shared passphrase');

A descriptografia usa um chaveiro com as suas chaves secretas. Uma chave bloqueada é desbloqueada em uma cópia privada com a senha, de modo que o chaveiro em si nunca muda. O resultado informa para quem a mensagem era destinada, como foi criptografada e se a assinatura interna é válida.

var
  oRing: TsgcPGPKeyRing;
  vResult: TsgcPGPDecryptResult;
begin
  oRing := TsgcPGPKeyRing.Create;
  try
    oRing.LoadFromFile('bob-secret.asc');
    vData := sgcPGP_Decrypt(vEncrypted, oRing, 'bob passphrase', oContacts,
      vResult);
    if vResult.Verify.Valid then
      Log('Signed by ' + vResult.Verify.SignerUserID);
  finally
    oRing.Free;
  end;
end;

Assine e Verifique

Há suporte a assinaturas separadas para arquivos e releases, mensagens assinadas inline e assinaturas em texto claro para textos que precisam continuar legíveis, com modo texto para assinaturas independentes do fim de linha.

// detached signature, the classic file.sig
vSignature := sgcPGP_Sign(vData, oAlice);
if sgcPGP_VerifyDetached(vData, vSignature, oContacts, vVerify) then
  Log('Valid signature from ' + vVerify.SignerUserID);

// cleartext signed text, readable without any tool
vSigned := sgcPGP_ClearSign('Payment batch 2026-10 approved', oAlice);

Funciona com o GnuPG

Cada recurso foi testado nos dois sentidos contra o GnuPG 2.4.5: arquivos e assinaturas feitos pelo GnuPG são descriptografados e verificados em Delphi, e tudo o que a biblioteca produz é aceito por gpg --decrypt e gpg --verify. Isso inclui as mensagens criptografadas com OCB que o GnuPG 2.4 grava por padrão para as chaves que ele gerou, e que muitas bibliotecas OpenPGP não conseguem ler. O suporte à versão 6 foi conferido com as chaves e mensagens de exemplo da RFC 9580.

As chaves circulam entre os dois mundos como texto armored. Exporte uma chave do Delphi e execute gpg --import, ou carregue a saída de gpg --export --armor em um TsgcPGPKeyRing.

Feito para Entrada Não Confiável

Uma aplicação que descriptografa arquivos vindos de fora precisa presumir que alguns deles são hostis. A biblioteca recusa o antigo formato de criptografia sem proteção, informa toda falha de descriptografia com o mesmo erro para que ela não sirva de oráculo, rejeita assinaturas SHA-1 em documentos e tem limites para o fator de trabalho das senhas e para o tamanho descomprimido, de modo que uma mensagem forjada não consiga paralisar o servidor.

O Que Mais Há de Novo

As units do OpenPGP compilam do Delphi 7 ao Delphi 13 e no C++Builder, para Win32 e Win64. Chaves DSA e ElGamal podem ser carregadas, mas não usadas, e as cifras antigas CAST5, 3DES e IDEA não são suportadas.

Leia também

Dúvidas sobre uma integração específica, um formato bancário ou uma chave que você precisa importar? Entre em contato. Você receberá a resposta das pessoas que escreveram o código.