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:
- ML-KEM (FIPS 203) komt een gedeeld geheim overeen. Het vervangt de taak die Diffie-Hellman vandaag vervult.
- ML-DSA (FIPS 204) ondertekent. Het vervangt RSA- en ECDSA-handtekeningen.
- SLH-DSA (FIPS 205) ondertekent ook, uitsluitend gebouwd op hashfuncties, voor het geval u de meest conservatieve aanname wilt die beschikbaar is en de omvang van de handtekening kunt veroorloven.
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:
- TLS. De native TLS 1.3-engine onderhandelt over de hybride sleuteluitwisselingsgroepen van RFC 10024,
X25519MLKEM768,SecP256r1MLKEM768enSecP384r1MLKEM1024, en de standaardlijst begint al met een hybride groep. Zie Delphi TLS 1.3 zonder OpenSSL-DLL's. - JWT. Tokens kunnen worden ondertekend en geverifieerd met ML-DSA volgens RFC 9964. Zie Een JWT ondertekenen met ML-DSA in Delphi.
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
- Delphi TLS 1.3 zonder OpenSSL-DLL's
- Een JWT ondertekenen met ML-DSA in Delphi
- sgcWebSockets 2026.10, al het andere in deze release
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.
