Post-kwantumcryptografie in Delphi

· Componenten
Post-kwantumcryptografie in Delphi

Er is een vraag die het waard is te stellen over de gegevens die uw toepassing vandaag verwerkt: hoe lang blijven ze gevoelig? Een medisch dossier, een contract, een loonbestand, een reeks inloggegevens. Als het antwoord meer dan een paar jaar is, dan is de interessante dreiging niet een aanvaller die uw versleuteling nu breekt. Het is een aanvaller die het verkeer nu opneemt, opslaat en later ontsleutelt, wanneer de hulpmiddelen zijn bijgebeend. Deze gewoonte heeft een naam, nu oogsten, later ontsleutelen, en daarvoor hoeft niemand vandaag al een kwantumcomputer te bouwen. Het is voldoende dat ze geloven dat iemand dat ooit zal doen.

Daarom bewogen de standaarden als eerste. NIST publiceerde de algoritmen in 2024, browsers en CDN's schakelden in de loop van 2025 hybride sleuteluitwisseling in, en de deadlines voor het uitfaseren van RSA en sleuteluitwisseling met elliptische krommen staan inmiddels in openbare richtlijnen. sgcWebSockets 2026.10 brengt de hele set naar Delphi, geschreven in Object Pascal binnen het sgcCrypto-pakket, zonder externe bibliotheek om te installeren of mee te leveren.

Drie algoritmen, één pakket

De drie NIST-standaarden vervullen verschillende taken, en normaal gesproken gebruikt u de eerste twee:

Een sleutel overeenkomen met ML-KEM

Een sleutelinkapselingsmechanisme is eenvoudiger te gebruiken dan Diffie-Hellman. De verzender neemt de publieke sleutel van de ontvanger en produceert twee dingen: een vers gedeeld geheim en een cijfertekst die het aflevert. De ontvanger zet de cijfertekst weer om in datzelfde geheim.

uses
  sgcCrypto_MLKEM;

var
  oPublicKey, oPrivateKey, oCiphertext, oSecret, oSame: TBytes;
begin
  sgcMLKEM_GenerateKeyPair(mlkem768, oPublicKey, oPrivateKey);

  // the sender, who only ever sees the public key
  sgcMLKEM_Encapsulate(mlkem768, oPublicKey, oCiphertext, oSecret);

  // the recipient, who holds the private key, gets the same 32 bytes
  oSame := sgcMLKEM_Decapsulate(mlkem768, oPrivateKey, oCiphertext);
end;

De parametersets zijn mlkem512, mlkem768 en mlkem1024. De invoercontroles die FIPS 203 vereist, worden als eerste uitgevoerd, zodat een misvormde publieke sleutel een uitzondering veroorzaakt in plaats van stilzwijgend een geheim te produceren, en een cijfertekst die niet ontsleutelt een pseudowillekeurig geheim oplevert in plaats van een fout, wat de impliciete afwijzing is die de standaard vereist.

X-Wing, wanneer u niet wilt kiezen

Een nieuw algoritme overnemen betekent er vertrouwen in stellen. Hybride constructies nemen die beslissing weg: ze combineren een klassiek algoritme met een post-kwantumalgoritme, zodat het resultaat veilig is zolang een van beide helften standhoudt. X-Wing combineert X25519 met ML-KEM-768 en biedt één enkel sleutelpaar.

uses
  sgcCrypto_MLKEM_Hybrid;

var
  oPublicKey, oPrivateKey, oCiphertext, oSecret: TBytes;
begin
  sgcXWing_GenerateKeyPair(oPublicKey, oPrivateKey);
  sgcXWing_Encapsulate(oPublicKey, oCiphertext, oSecret);
  oSecret := sgcXWing_Decapsulate(oPrivateKey, oCiphertext);
end;

Ondertekenen met ML-DSA

Ondertekenen vereist de parameterset, de private sleutel, het bericht en een contextreeks, die normaal gesproken leeg is:

uses
  sgcCrypto_MLDSA;

var
  oSeed, oPublicKey, oPrivateKey, oSignature: TBytes;
begin
  sgcMLDSA_GenerateKeyPairAndSeed(mldsa65, oSeed, oPublicKey, oPrivateKey);

  oSignature := sgcMLDSA_Sign(mldsa65, oPrivateKey, aMessage, nil);

  if sgcMLDSA_Verify(mldsa65, oPublicKey, aMessage, oSignature, nil) then
    ShowMessage('signature is valid');
end;

Let op de seed. Een private ML-DSA-sleutel kan worden opgeslagen als de 32 bytes waaruit hij is gegenereerd, als de uitgebreide sleutel, of als beide, en de bibliotheek leest en schrijft alle drie de vormen. De seed is de vorm die u in een configuratiebestand wilt: hij is klein, en de uitgebreide sleutel wordt er deterministisch van afgeleid.

Sleutels die reizen

Een algoritme waarmee niemand sleutels kan uitwisselen, heeft weinig nut, dus volgen de coderingen de gepubliceerde profielen: SubjectPublicKeyInfo en PKCS#8, in DER of PEM, volgens RFC 9935 voor ML-KEM, RFC 9881 voor ML-DSA en RFC 9909 voor SLH-DSA.

var
  vPublicPEM, vPrivatePEM: string;
begin
  vPublicPEM := sgcMLDSA_ExportPublicKeyPEM(mldsa65, oPublicKey);
  vPrivatePEM := sgcMLDSA_ExportPrivateKeyPEM(mldsa65, oSeed, nil);
end;

Dat zijn gewone BEGIN PUBLIC KEY- en BEGIN PRIVATE KEY-blokken die andere implementaties kunnen lezen. Een private sleutel wordt gecontroleerd bij het importeren: de publieke helft wordt opnieuw afgeleid en vergeleken, zodat een sleutel die niet bij zijn certificaat hoort, meteen wordt geweigerd in plaats van handtekeningen te produceren die niemand kan verifiëren.

Certificaten en een post-kwantum CA

Certificaten en certificaataanvragen kunnen post-kwantumsleutels bevatten, en ook een certificeringsinstantie kan er een hebben, zodat een hele keten post-kwantum kan zijn:

var
  vKey: TsgcX509SignKey;
  vOptions: TsgcX509Options;
  oCertDER: TBytes;
begin
  vKey := sgcX509_MLDSAKey(mldsa65, oPrivateKey, oPublicKey);
  vOptions.Subject.CommonName := 'My Post-Quantum CA';
  vOptions.KeyUsage := [kuKeyCertSign, kuCRLSign];
  oCertDER := sgcX509_CreateSelfSignedEx(vKey, vOptions);
end;

De regels voor sleutelgebruik van de profielen worden afgedwongen voordat er iets wordt ondertekend, zodat een post-kwantumsleutel die wordt gevraagd voor sleutelversleuteling een uitzondering veroorzaakt in plaats van een certificaat te produceren dat zijn eigen profiel schendt. Kettingvalidatie dwingt nu ook de padlengte en de naambeperkingen af die de uitgevende certificaten declareren.

Waar het al is ingebouwd

Twee plekken in de bibliotheek gebruiken dit allemaal al voor u, zonder dat u zelf cryptografie hoeft te schrijven:

Hoe we weten dat het klopt

Een implementatie van een standaard is niet meer dan een bewering totdat iets ze controleert. Alle drie de algoritmen worden gevalideerd tegen de bekende NIST-testvectoren, en die vectoren worden met de bibliotheek meegeleverd als een uitvoerbare testset, niet als een zin in een datasheet. De ML-DSA-ondertekenaar is de deterministische variant, zodat dezelfde sleutel en hetzelfde bericht altijd dezelfde handtekening opleveren, wat de gepubliceerde voorbeelden in de RFC's byte voor byte reproduceerbaar maakt.

Welke moet u gebruiken

Gebruik voor sleuteluitwisseling een hybride: X-Wing alleen, of de hybride TLS-groepen als het verkeer TLS is. U levert bijna niets in en bent gedekt, welke aanname ook onjuist blijkt. Voor handtekeningen is ML-DSA-65 de verstandige standaardkeuze, met ML-DSA-44 wanneer omvang belangrijk is en ML-DSA-87 wanneer dat niet zo is. Grijp naar SLH-DSA wanneer de handtekening over vele jaren zal worden geverifieerd door iets dat u niet kunt bijwerken, zoals firmware, en de omvang van de handtekening betaalbaar is.

Upgraden

Dit alles zit in het sgcCrypto-pakket en voegt geen afhankelijkheid toe: geen OpenSSL, geen DLL, niets om te installeren op de machine die uw toepassing uitvoert. Bestaande code blijft ongewijzigd totdat u ze aanroept.

Lees ook

Bekijk het

Er staat een korte video hierover op het eSeGeCe-kanaal.

Vragen, feedback of hulp bij migratie? Neem contact op — u krijgt een antwoord van de mensen die de code hebben geschreven.