Kvantno programiranje

Postkvantna enkripcija u Javi: šta donosi JDK 27 i kako je koristiti već danas

18. septembar 2026. Ažurirano 18.09.2026
Postkvantna enkripcija u Javi: šta donosi JDK 27 i kako je koristiti već danas
Vodič · Kvantno programiranje

Postkvantna enkripcija u Javi: šta donosi JDK 27 i kako je koristiti već danas

Objavljeno: 18. septembar 2026. · PsiMosaic

Java 27 je izašla 16. septembra 2026. i sa njom je postkvantna kriptografija prvi put stigla tamo gde je zaista potrebna — u TLS rukovanje, i to bez ijedne izmene u vašem kodu. U ovom tekstu prolazimo kroz ceo put: šta je JDK dobio kada, kako se hibridna razmena ključeva podešava, koliko košta u bajtovima, kako ML-KEM i ML-DSA koristiti direktno, i šta uraditi ako ste zaglavljeni na Javi 8.

Zašto sada: rok je već postavljen

O motivu smo pisali detaljno: Evropska komisija i države članice usvojile su mapu puta po kojoj kritična infrastruktura mora biti na postkvantnim algoritmima do kraja 2030, a sve ostalo do 2035. Pokretač nije kvantni računar koji postoji danas, nego napad „harvest now, decrypt later” — snimi sada, dešifruj kasnije.

Za Java tim to znači vrlo konkretnu stvar: saobraćaj koji vaša aplikacija danas šalje preko TLS-a neko može da arhivira i otvori za deset godina. Ako podaci u toj sesiji imaju rok poverljivosti duži od toga, zaštita mora da se ugradi sada, a ne kada hardver stigne.

Put JDK-a do kvantne otpornosti

Oracle ovo ne radi od juče. Gradnja je tekla u slojevima, izdanje po izdanje, i tek u JDK 27 se slojevi spajaju u nešto što radi samo od sebe.

IzdanjeŠta je donetoJEP
JDK 21 (LTS, 2023)Generički KEM API — apstrakcija za enkapsulaciju ključeva, bez ijednog postkvantnog algoritmaJEP 452
JDK 24 (mart 2025)ML-KEM (FIPS 203) i ML-DSA (FIPS 204) kao ugrađeni algoritmi; KDF APIJEP 496, 497, 510
JDK 25 (LTS, sept. 2025)Nasleđuje ML-KEM i ML-DSA — prvi LTS sa postkvantnim algoritmima
JDK 26 (mart 2026)Potpisivanje JAR-ova pomoću ML-DSA; HPKE (RFC 9180); PEM APIJEP 524
JDK 27 (16. 9. 2026)Hibridna postkvantna razmena ključeva za TLS 1.3; PEM API (treći pregled)JEP 527, 538

Obratite pažnju na logiku: prvo API (21), pa algoritmi (24), pa alati (26), pa protokol (27). Svaki korak je bio upotrebljiv sam za sebe — ali tek JEP 527 daje ono što većina timova zapravo želi: zaštitu koja se uključuje bez pisanja koda.

Java 27 nije LTS izdanje, što je za produkciju bitno. Oracle je zato najavio i backport hibridnog TLS-a na LTS linije: JDK 25 sa oktobarskim kvartalnim zakrpama 2026, JDK 21 i 17 u prvoj polovini 2027, a JDK 11 i 8 u drugoj polovini 2027. Ako danas držite produkciju na JDK 21, ne morate da skačete na 27 — ali morate da planirate nadogradnju zakrpa.

JEP 527: šta se tačno promenilo u TLS-u

Suština JEP-a 527 je da SunJSSE provajder dobija tri nove „imenovane grupe” (named groups) za razmenu ključeva u TLS 1.3:

  • X25519MLKEM768 — X25519 ECDHE + ML-KEM-768 (nova podrazumevana vrednost)
  • SecP256r1MLKEM768 — secp256r1 ECDHE + ML-KEM-768
  • SecP384r1MLKEM1024 — secp384r1 ECDHE + ML-KEM-1024

Ključna reč je hibridna. Ne zamenjuje se eliptička kriva postkvantnim algoritmom — obe se izvode u istom rukovanju, a njihove tajne se nadovezuju jedna na drugu pre ulaska u HKDF. Konstrukciju je definisao IETF u RFC 9954 (opšti okvir) i RFC 10024 (baš ove tri šeme), a garancija koju daje je elegantna: veza ostaje bezbedna sve dok je bar jedan od dva algoritma neprobijen.

To je osiguranje u oba smera. Ako se sutra pojavi kvantni računar, štiti vas ML-KEM. Ako se u rešetkastoj matematici nađe rupa — a ML-KEM je mnogo mlađi od X25519 — štiti vas klasična kriva.

Hibridna razmena ključeva u TLS 1.3: ML-KEM-768 i X25519 u istom rukovanju.
Hibridno rukovanje X25519MLKEM768 — udeli ključa i izvođenje zajedničke tajne.

U JDK 27 podrazumevani redosled preferencija izgleda ovako:

X25519MLKEM768, x25519, secp256r1, secp384r1,
secp521r1, x448, ffdhe2048, ffdhe3072, ffdhe4096

Klijent pritom šalje dva udela ključa — jedan hibridni i jedan klasični — pa rukovanje sa starijim serverom prolazi iz prve, bez dodatne runde.

Ako koristite standardni javax.net.ssl, ne morate da uradite ništa. HttpClient, SSLSocket, Tomcat, Netty preko JSSE-a, JDBC drajveri nad TLS-om — svi automatski dobijaju hibridnu razmenu. Jedini izuzetak su aplikacije koje su eksplicitno postavile listu imenovanih grupa; njih treba ručno dopuniti.

Cena: rukovanje postaje 38 puta veće

Ovo je deo koji vas može iznenaditi u produkciji. Klasičan x25519 udeo ključa je 32 bajta. Hibridni X25519MLKEM768 udeo je 1216 bajtova — 1184 za ML-KEM-768 enkapsulacioni ključ plus 32 za X25519.

Veličine postkvantnih ključeva, šifrata i potpisa u poređenju sa klasičnim algoritmima.
Cena otpornosti: key_share u TLS-u raste sa 32 na 1216 bajtova.

Posledica: ClientHello više ne staje u jedan mrežni paket. Većina mreže to podnese bez problema, ali deo starijih firewall i DPI uređaja, kao i pojedini load balancer-i, tiho odbacuju prevelik ClientHello. Rezultat je veza koja „ne radi ni zbog čega” — i to je danas najčešći praktičan problem sa hibridnim TLS-om, a ne performanse. Same lattice operacije su brze; ML-KEM je po procesorskom vremenu uporediv sa ECDHE, ponekad i brži.

Kako podesiti ili isključiti

Dva su načina. Sistemsko svojstvo, globalno za JVM:

# samo klasični algoritmi — privremeno gašenje hibrida
java -Djdk.tls.namedGroups=x25519,secp256r1 -jar app.jar

# eksplicitan redosled sa hibridima
java -Djdk.tls.namedGroups=X25519MLKEM768,SecP256r1MLKEM768,x25519,secp256r1 -jar app.jar

Ili programski, po konekciji:

SSLParameters params = socket.getSSLParameters();
params.setNamedGroups(new String[] {
    "X25519MLKEM768",
    "SecP256r1MLKEM768",
    "x25519",
    "secp256r1"
});
socket.setSSLParameters(params);

Dijagnostika

Od JDK-a 26 postoji brz način da vidite šta je zaista uključeno:

java -XshowSettings:security:tls -version

A kada rukovanje pukne, klasika i dalje radi najbolje:

java -Djavax.net.debug=ssl,handshake -jar app.jar

U ispisu tražite named groups i key_share — tu se vidi da li je hibridna grupa ponuđena i da li ju je server prihvatio.

Sloj niže: ML-KEM direktno

TLS pokriva podatke u prenosu. Za sve ostalo — enkripciju u mirovanju, sopstvene protokole, razmenu ključeva između mikroservisa, šifrovanje poruka u redu — algoritam koristite sami, preko KEM API-ja iz JDK-a 21.

Prvo, generisanje para ključeva. Dva ekvivalentna oblika:

import java.security.*;
import java.security.spec.NamedParameterSpec;

// oblik 1: porodica + parametarski skup
KeyPairGenerator g = KeyPairGenerator.getInstance("ML-KEM");
g.initialize(NamedParameterSpec.ML_KEM_768);
KeyPair kp = g.generateKeyPair();

// oblik 2: direktno po imenu skupa
KeyPairGenerator g2 = KeyPairGenerator.getInstance("ML-KEM-768");
KeyPair kp2 = g2.generateKeyPair();

Bez initialize, podrazumevani skup je ML-KEM-768 — i to je pravi izbor za skoro sve. ML-KEM-512 štedi malo prostora po ceni sigurnosne margine, a ML-KEM-1024 je za podatke sa vrlo dugim rokom poverljivosti.

Sada razmena. Pošiljalac ima samo javni ključ primaoca i iz njega izvodi dve stvari odjednom — tajni ključ i šifrat koji taj ključ prenosi:

import javax.crypto.KEM;
import javax.crypto.SecretKey;

// --- strana koja šalje ---
KEM kem = KEM.getInstance("ML-KEM");
KEM.Encapsulator enc = kem.newEncapsulator(kp.getPublic());
KEM.Encapsulated result = enc.encapsulate();

byte[] sifrat = result.encapsulation();   // 1088 B za ML-KEM-768 — ide preko mreže
SecretKey kljucPosiljaoca = result.key(); // ostaje kod pošiljaoca

// --- strana koja prima ---
KEM.Decapsulator dec = kem.newDecapsulator(kp.getPrivate());
SecretKey kljucPrimaoca = dec.decapsulate(sifrat);

// kljucPosiljaoca i kljucPrimaoca su isti bajtovi

Ovo je mentalno drugačije od Diffie–Hellmana i vredi se zadržati na tome. Kod DH-a obe strane doprinose i zajednički izvode tajnu. Kod KEM-a pošiljalac sam proizvede tajnu i zapakuje je tako da je samo vlasnik privatnog ključa može otvoriti. Praktična posledica: razmena je asimetrična i staje u jednu poruku.

Dobijeni SecretKey se ne koristi direktno za šifrovanje. Provucite ga kroz KDF (HKDF je u JDK-u od 24, JEP 510) da biste izveli zasebne ključeve za AES-GCM i za autentikaciju.

Serijalizacija ključeva ide uobičajenim putem, preko KeyFactory:

import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;

KeyFactory f = KeyFactory.getInstance("ML-KEM");

X509EncodedKeySpec javni = f.getKeySpec(kp.getPublic(), X509EncodedKeySpec.class);
PKCS8EncodedKeySpec privatni = f.getKeySpec(kp.getPrivate(), PKCS8EncodedKeySpec.class);

PublicKey vracenJavni = f.generatePublic(javni);

Potpisi: ML-DSA

ML-KEM rešava poverljivost. Za integritet i autentičnost tu je ML-DSA, koji se u JDK-u koristi kroz standardni Signature API:

KeyPairGenerator g = KeyPairGenerator.getInstance("ML-DSA");
g.initialize(NamedParameterSpec.ML_DSA_65);   // podrazumevano i bez ove linije
KeyPair kp = g.generateKeyPair();

byte[] poruka = "ugovor".getBytes(StandardCharsets.UTF_8);

Signature potpisivac = Signature.getInstance("ML-DSA");
potpisivac.initSign(kp.getPrivate());
potpisivac.update(poruka);
byte[] potpis = potpisivac.sign();          // 3309 B za ML-DSA-65

Signature proveravac = Signature.getInstance("ML-DSA");
proveravac.initVerify(kp.getPublic());
proveravac.update(poruka);
boolean ispravno = proveravac.verify(potpis);

Alati prate. keytool generiše ML-DSA par:

keytool -keystore ks -storepass changeit -genkeypair -alias mldsa \
        -keyalg ML-DSA -groupname ML-DSA-65 -dname CN=ML-DSA

A od JDK-a 26 i jarsigner ume da potpiše JAR postkvantnim potpisom, uz identifikator algoritma ML-DSA-65. To je nenametljiv, ali važan detalj: lanac isporuke softvera je upravo mesto gde potpis mora da izdrži decenije, jer se artefakt potpisuje jednom a verifikuje godinama.

Ono što ovde boli je veličina. ML-DSA-65 potpis je 3309 bajtova naspram 256 za RSA-2048 — trinaest puta više. Ako potpise stavljate u JWT tokene, u HTTP zaglavlja ili u bazu po redu tabele, to više nije zanemarljiva stavka. Proverite limite na zaglavljima (mnogi reverse proxy-ji podrazumevano seku na 8 KB) pre nego što nešto pređe na ML-DSA.

Šta još ne radi

Da ne bi bilo iznenađenja, evo granica onoga što je isporučeno.

Autentikacija u TLS-u i dalje je klasična. JEP 527 pokriva samo razmenu ključeva. Sertifikati kojima se server predstavlja i dalje su RSA ili ECDSA. To za „harvest now, decrypt later” nije problem — potpis se proverava u trenutku rukovanja, pa retroaktivno probijanje ne pomaže napadaču — ali znači da PKI migracija tek predstoji. Postkvantni sertifikati javnih CA tela još nisu praktično dostupni; ne kupujte ih za produkciju u 2026.

Čist ML-KEM, bez hibrida, nije podržan. To je izričit ne-cilj JEP-a 527. IETF nacrt draft-ietf-tls-mlkem koji definiše samostalne grupe mlkem512, mlkem768 i mlkem1024 (kodne tačke 0x0200–0x0202) trenutno je u redu za objavu kao RFC. Podrška u JDK-u ostaje za kasnije — i to je razumna odluka, jer je hibrid danas jedino što regulatori i NIST preporučuju.

SLH-DSA i HQC nisu u JDK-u. Ako vam treba potpis zasnovan isključivo na heš funkcijama (FIPS 205) ili rezervni KEM nezavisan od rešetki, morate van standardne biblioteke.

HPKE iz JDK-a 26 je za sada klasičan. Podržava X25519, AES-GCM i KDF-ove nad SHA-256; postkvantne varijante čekaju da odgovarajući IETF nacrti postanu RFC.

Ako ste na starijoj Javi: Bouncy Castle

Realnost je da ogroman broj poslovnih sistema u Srbiji stoji na JDK 8, 11 ili 17. Backport hibridnog TLS-a tamo stiže tek 2027, a KEM API postoji tek od 21. Rešenje je Bouncy Castle, koji od verzije 1.79 nosi pune implementacije ML-KEM, ML-DSA i SLH-DSA i registruje se kao običan JCE provajder:

import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.jcajce.spec.MLKEMParameterSpec;

Security.addProvider(new BouncyCastleProvider());

KeyPairGenerator g = KeyPairGenerator.getInstance("ML-KEM", "BC");
g.initialize(MLKEMParameterSpec.ml_kem_768);
KeyPair kp = g.generateKeyPair();

Za ML-DSA je isto, uz MLDSAParameterSpec.ml_dsa_65. Dve napomene: na JDK-u starijem od 21 nemate javax.crypto.KEM, pa se koristi niži BC API; i ako vam treba FIPS 140-3 validacija, to je zaseban proizvod (bc-fips), ne standardni bcprov.

Plan za Java tim — šest koraka

  1. Popišite gde se kriptografija zaista koristi. Pretražite kod za RSA, ECDSA, DH, SSLContext, KeyStore, Signature.getInstance. Naći ćete više mesta nego što očekujete, a najčešće u bibliotekama koje niste vi pisali.
  2. Pronađite ko je „zakucao” imenovane grupe. Svaki poziv setNamedGroups ili postavljeno jdk.tls.namedGroups tiho blokira hibrid. To je jedini kod koji mora da se menja.
  3. Testirajte mrežnu putanju, ne samo aplikaciju. Podignite JDK 27 u test okruženju i propustite saobraćaj kroz iste firewall-e, proxy-je i load balancer-e kao u produkciji. Veliki ClientHello je problem infrastrukture, a ne koda — i neće se pokazati na lokalnoj mašini.
  4. Rangirajte podatke po roku poverljivosti. Sesija koja prenosi medicinske ili ugovorne podatke ima prioritet nad onom koja vuče sličice proizvoda.
  5. Uvedite kriptografsku agilnost. Ime algoritma neka bude konfiguracija, ne literal u kodu. Sledeća smena dolazi brže nego prethodna.
  6. Uskladite se sa LTS rasporedom. Ako ste na JDK 21, ciljajte zakrpe iz 2027. Ako ste na 25, oktobarske zakrpe 2026. Ako ste na 8 — nadogradnja Jave vam je ionako veći projekat od postkvantne kriptografije.

Zaključak

Java je sa JDK-om 27 stigla do tačke u kojoj postkvantna zaštita prestaje da bude tema za istraživanje i postaje podrazumevano ponašanje. Za većinu timova to znači da najvažniji posao nije pisanje novog koda, već provera da li nešto u postojećoj konfiguraciji stoji na putu — zakucana lista grupa, stari firewall, ili LTS izdanje koje čeka svoju zakrpu.

Onaj drugi deo — ML-KEM i ML-DSA u sopstvenom kodu — nije hitan za sve, ali jeste za one koji čuvaju podatke sa dugim rokom. Lepa vest je da su API-ji obični, poznati i već u standardnoj biblioteci. Nema egzotike: KeyPairGenerator, Signature, KeyFactory. Samo drugi algoritmi iza njih.


Izvori: InfoQ, „Java 27 Released” (16. septembar 2026); OpenJDK JEP 452, 496, 497, 510, 524, 527 i 538; Oracle Java blog, „Post-Quantum Cryptography in Long-Term Support JDK Releases” (avgust 2026); Inside.java, „Post-Quantum Hybrid Key Exchange for TLS 1.3”; IETF RFC 9954 i RFC 10024, nacrt draft-ietf-tls-mlkem; NIST FIPS 203 i FIPS 204; dokumentacija Bouncy Castle 1.79+. Tekst je autorska obrada PsiMosaic redakcije.


Komentari

Još nema komentara. Budite prvi!

Dodaj komentar