OpenPGP nadal jest sposobem, w jaki wiele organizacji wymienia pliki. Bank oczekuje paczek płatności zaszyfrowanych jego kluczem publicznym, partner wysyła raporty zaszyfrowane GnuPG, a wydanie musi być opatrzone podpisem odłączonym. Z poziomu Delphi zwykle oznaczało to instalowanie GnuPG na każdej maszynie i wywoływanie gpg.exe z wiersza poleceń, wraz z całą obsługą ścieżek, kluczeników i kodów wyjścia, która się z tym wiąże.
sgcCrypto implementuje teraz OpenPGP samodzielnie, w czystym Object Pascal. Nie ma DLL do wdrożenia, nie ma narzędzia wiersza poleceń do wywoływania i nie ma zależności od Indy. Klucze, szyfrowanie, deszyfrowanie, podpisy i weryfikacja to kilka wywołań funkcji na TBytes, a wynik współpracuje z GnuPG w obu kierunkach.
Wersja 4 i wersja 6
Obsługiwane są dwie generacje formatu:
- Wersja 4 (RFC 4880 i RFC 6637) jest używana dziś przez GnuPG, Kleopatrę i większość klientów poczty. Wybierz ją, gdy wymieniasz klucze i pliki z istniejącymi narzędziami.
- Wersja 6 (RFC 9580) jest aktualnym standardem. Dodaje szyfrowanie uwierzytelnione (AEAD z OCB, EAX lub GCM), Argon2 dla haseł oraz natywne klucze Ed25519, Ed448, X25519 i X448.
Gdy szyfrujesz dla wielu odbiorców, biblioteka wybiera format, który potrafią odczytać wszyscy: format AEAD z RFC 9580, jeśli obsługują go wszyscy, a w przeciwnym razie klasyczny format z ochroną integralności. Wiadomość do mieszanki starych i nowych kluczy otworzy się wszędzie.
Generowanie klucza
Jedno wywołanie tworzy kompletny klucz: główny klucz podpisujący, podklucz szyfrujący, identyfikator użytkownika oraz samopodpisy, które je wiążą.
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;
Dostępne typy kluczy to RSA 2048, 3072 i 4096, Ed25519, Ed448 (wersja 6) oraz ECDSA z ECDH na NIST P-256, P-384 i P-521. Klucze Brainpool można importować. Klucze tajne są chronione Twoim hasłem, z użyciem iterowanego SHA-256 w wersji 4 oraz Argon2 z AES-OCB w wersji 6.
Szyfrowanie i deszyfrowanie
Szyfruj dla jednego lub wielu kluczy publicznych, opcjonalnie z podpisem nadawcy. Wynik jest domyślnie w formacie ASCII armor, gotowy do dołączenia do wiadomości lub wysłania na serwer.
// 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');
Deszyfrowanie korzysta z kluczenika z Twoimi kluczami tajnymi. Zablokowany klucz jest odblokowywany hasłem na prywatnej kopii, więc sam kluczenik nigdy się nie zmienia. Wynik informuje, dla kogo była wiadomość, jak została zaszyfrowana i czy zawarty w niej podpis jest poprawny.
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;
Podpisywanie i weryfikacja
Obsługiwane są podpisy odłączone dla plików i wydań, podpisane wiadomości inline oraz podpisy cleartext dla tekstu, który ma pozostać czytelny, z trybem tekstowym dla podpisów niezależnych od znaków końca wiersza.
// 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);
Współpracuje z GnuPG
Każda funkcja została przetestowana w obie strony z GnuPG 2.4.5: pliki i podpisy utworzone przez GnuPG są deszyfrowane i weryfikowane w Delphi, a wszystko, co tworzy biblioteka, jest akceptowane przez gpg --decrypt i gpg --verify. Dotyczy to także wiadomości szyfrowanych OCB, które GnuPG 2.4 domyślnie zapisuje dla wygenerowanych przez siebie kluczy, a których wiele bibliotek OpenPGP nie potrafi odczytać. Obsługę wersji 6 sprawdzono na przykładowych kluczach i wiadomościach z RFC 9580.
Klucze przechodzą między oboma światami jako tekst armor. Wyeksportuj klucz z Delphi i uruchom gpg --import albo wczytaj wynik gpg --export --armor do TsgcPGPKeyRing.
Zbudowane na niezaufane dane
Aplikacja, która deszyfruje pliki z zewnątrz, musi zakładać, że część z nich jest wroga. Biblioteka odrzuca stary format szyfrowania bez ochrony, zgłasza każdy błąd deszyfrowania tym samym komunikatem, aby nie dało się go użyć jako wyroczni, odrzuca podpisy SHA-1 na dokumentach oraz ma limity dla kosztu przetwarzania haseł i rozmiaru po dekompresji, aby spreparowana wiadomość nie mogła zająć serwera.
Co jeszcze nowego
- Szyfrowanie uwierzytelnione AES-OCB (RFC 7253) i AES-EAX, dostępne samodzielnie w sgcCrypto.
- Kompresja DEFLATE i ZLIB w nowej jednostce w czystym Object Pascal,
sgcCrypto_Deflate. - Demo VCL,
Demos\18.Cryptography\09.OpenPGP, z generowaniem kluczy, importem i eksportem, szyfrowaniem, deszyfrowaniem, podpisywaniem i weryfikacją w jednym oknie.
Jednostki OpenPGP kompilują się w Delphi 7 do Delphi 13 oraz C++Builder, dla Win32 i Win64. Klucze DSA i ElGamal można wczytać, ale nie można ich używać, a stare szyfry CAST5, 3DES i IDEA nie są obsługiwane.
Czytaj dalej
- Kryptografia postkwantowa w Delphi
- OpenSSL czy natywna kryptografia w Delphi: wybór w czasie działania
- sgcCrypto, wszystko w pakiecie kryptograficznym
Pytania o konkretną integrację, format bankowy lub klucz, który musisz zaimportować? Skontaktuj się z nami. Odpowie Ci zespół, który napisał ten kod.
