RSA Encrypt / Decrypt

Generér RSA-nøglepar i browseren, kryptér og dekryptér med RSA-OAEP, signér med RSA-PSS eller PKCS#1 v1.5, og konvertér nøgler mellem SPKI-, PKCS#8- og PKCS#1-PEM-formater. Alt kører lokalt med WebCrypto-motoren — ingen nøgle eller besked forlader denne side.
Hvad RSA er til: små beskeder og signaturer, ikke store datamængder. RSA krypterer højst k−2·hashLen−2 byte pr. kald (190 byte for en 2048-bit nøgle med SHA-256) og er ~1000× langsommere end AES. Rigtige systemer bruger hybridkryptering: RSA pakker en tilfældig AES-nøgle ind, AES krypterer dataene (se AES-værktøjet). Denne side findes til læring, test og interop-kontrol.
Modulstørrelse:
Hash: Label:
PKCS#1 v1.5-kryptering er bevidst ikke implementeret: den har ingen ciphertext-integritet og falder for padding-oracle-angreb (Bleichenbacher). OAEP er den eneste krypteringstilstand, et nyt design bør bruge.
Skema: Hash:
Skema: Hash:
Hvor meget kan ét RSA-kald bære? OAEP-beskedgrænse = nøglebyte − 2×hashbyte − 2:
ModulSHA-256SHA-384SHA-512
1024-bit62 byte30 byte0 bytes
2048-bit190 byte126 byte62 byte
3072-bit318 byte254 byte190 byte
4096-bit446 byte382 byte318 byte
Signaturer har ingen beskedgrænse — beskeden hashes først; selve signaturen er altid præcis nøglestørrelsen (256 byte for 2048-bit).
Nøglestyrke og levetid (NIST SP 800-57 Part 1 Rev. 5): 1024-bit blev forbudt til nye formål efter 2013; 2048-bit er minimum i dag og forbliver acceptabel frem til 2030; 3072-bit og derover er det komfortable valg fra 2031. 8192-bit virker her, men generering kan tage et minut eller mere i browseren og køber sikkerhed, ingen i dag har brug for — foretræk 3072/4096.
OpenSSL-interop — de PEM'er, denne side producerer, kan rundtures på kommandolinjen:
openssl pkeyutl -encrypt -pubin -inkey pub.pem -pkeyopt rsa_padding_mode:oaep -pkeyopt rsa_oaep_md:sha256 -pkeyopt rsa_mgf1_md:sha256
openssl pkeyutl -decrypt -inkey priv.pem -pkeyopt rsa_padding_mode:oaep ...
openssl dgst -sha256 -sign priv.pem -out msg.sig msg.txt (PKCS#1 v1.5)  /  openssl dgst -sha256 -verify pub.pem -signature msg.sig msg.txt
PSS: tilføj -sigopt rsa_padding_mode:pss -sigopt rsa_pss_saltlen:32 til begge dgst-kald. Nøgleformatkonvertering: openssl rsa -in key.pem -RSAPublicKey -out pubkey.pem laver SPKI ↔ PKCS#1 på disk; denne side gør det i browseren.
Selvtest
Kører sidemotoren mod uafhængige ankre: nøglegenerering i tre modulstørrelser, OAEP-kryptering/-dekryptering i rundture, PSS- og PKCS#1 v1.5-signér/verificér på tværs af hashes, en deterministisk v1.5-signaturvektor byte for byte (genereret af en uafhængig native implementering), en fast OAEP-ciphertext og PSS-signatur produceret af OpenSSL, som denne side skal dekryptere/verificere (krydsimplementerings-interop), PEM-formatkonverteringsrundture og negative tests (manipuleret signatur, forkert nøgle skal fejle). Intet sendes nogen steder hen.
RSA-kryptering og -signaturer forklaret fra bunden
I én sætning: RSA er offentlig-nøgle-kryptografi — enhver kan kryptere til en modtager med den offentlige nøgle eller verificere signaturer, men kun den private nøgle kan dekryptere eller signere — og dens sikkerhed hviler på, at det er umuligt for nuværende computere at faktorisere et 2048-bit tal i to primtal.
Hvad RSA faktisk beregner

To primtal og en bagdør. En RSA-nøgle starter som to store tilfældige primtal p og q; deres produkt n (modulet, deraf "2048-bit nøgle") offentliggøres i den offentlige nøgle sammen med en eksponent e (næsten altid 65537). Den private nøgle er parret d, den modulære inverse af e − beregnet ud fra p og q — plus genveje afledt af primtallene, der fremskynder operationer med den private nøgle 4×.

Kryptering og signering er den samme potensopløftning. At kryptere en beskedblok m betyder at beregne me mod n; dekryptering er cd mod n. At signere en præformateret blok med den private eksponent og verificere med den offentlige er den samme operation i den anden retning. Alt andet på denne side — OAEP, PSS, PKCS#1 — handler om at formatere blokken sikkert, så rå potensopløftning aldrig blotlægges.

Hvorfor den er langsom. En RSA-operation med en 2048-bit nøgle koster i størrelsesordenen en million gange mere CPU end at kryptere én blok med AES. Derfor bruger TLS kun RSA (eller ECC) til at aftale en tilfældig AES-nøgle og skifter derefter. Den samme regel gælder for alt, man bygger: RSA til nøglen, AES til data.

Nøglestørrelse. Modullængden er sikkerhedsknappen: 1024-bit er brudt efter politik (faktorisering er inden for rækkevidde for nationalstater), 2048-bit ≈ 112-bit symmetrisk styrke, 3072-bit ≈ 128-bit, 15360-bit ville svare til en 256-bit symmetrisk nøgle. Post-kvante-note: Shors algoritme bryder RSA fuldstændigt på en stor kvantecomputer — endnu en grund til at holde nøglers levetid begrænset.

OAEP: den eneste krypteringspolstring, man bør bruge

Problemet med rå RSA. Lærebogs-RSA (me mod n på den rå besked) er deterministisk og formbar: identiske beskeder krypteres ens, en angriber kan gange en ciphertext med krypteringen af 2 for at fordoble klarteksten, og korte beskeder falder for meet-in-the-middle. Den må aldrig bruges direkte.

Hvad OAEP gør. OAEP (PKCS#1 v2, RFC 8017) blander beskeden med et tilfældigt frø gennem et hashbaseret Feistel-netværk før potensopløftningen. Resultatet: kryptering er randomiseret (den samme klartekst giver en ny ciphertext hver gang — kør OAEP-eksemplet to gange, og sammenlign), manipulation opdages ved dekryptering, og beskeden skal passe inden for modulet med plads til hashen — den grænse på k−2·hashLen−2, der står i tabellen ovenfor.

Labelen. En valgfri offentlig streng bundet ind i polstringen. Begge sider skal angive præcis den samme label, ellers fejler dekrypteringen — ligesom AAD i AES-GCM lader den binde ciphertext til en kontekst (et filnavn, et algoritme-id). Tom er normalt.

PKCS#1 v1.5-kryptering er bevidst fraværende. Polstringen fra 1993 har ingen integritet og lækker information gennem dekrypteringsfejladfærd (Bleichenbachers angreb fra 1998 gør et padding-oracle til fuld dekryptering med et par millioner konstruerede ciphertexts; det bryder stadig rigtige systemer som ROBOT, 2017). WebCrypto nægter at implementere det; det gør denne side også.

PSS kontra PKCS#1 v1.5-signaturer

Signér = hash, derefter polstring, derefter potensopløftning. Begge skemaer hasher beskeden (SHA-256/384/512 her), formaterer digest'en i en blok og anvender den private eksponent. Verifikation formaterer blokken igen med den offentlige nøgle og sammenligner. Forskellen ligger i formateringen:

SkemaBlokindholdEgenskaber
RSASSA-PKCS1-v1_5digest + digest-info-header, deterministiskHver signatur af den samme besked er byte for byte identisk (tjek selvtesten: dens v1.5-vektor er fast). Universel ældre understøttelse: X.509-certifikater, JWT RS*, TLS før 1.3. Ingen kendt forfalskning, når verifikationen er korrekt implementeret.
RSA-PSSdigest + tilfældigt salt af hash-længde, MGF1-maskeringRandomiseret — hver signatur er forskellig. Beviseligt sikker i random-oracle-modellen; krævet i TLS 1.3-certifikater og nyere protokoller. Verifikatoren skal kende saltlængden (denne side bruger hash-længden, den almindelige standard).

Hvilket skal man vælge. Nye designs: PSS. Interop med eksisterende certifikater, JWT'er (RS256) eller gamle peers: v1.5. Begge er sikre som signaturskemaer — v1.5-katastrofehistorien handler om *kryptering*-polstring, en anden konstruktion på trods af det lignende navn.

PKCS#1 kontra PKCS#8 kontra SPKI: hvorfor den samme nøgle har fire PEM'er

PEM er blot base64-indpakket DER. En PEM-fil er et label plus base64 af en DER-struktur (binær ASN.1). Labelen fortæller, hvilken struktur — og det er hele forskellen mellem de fire formater, denne side genererer:

PEM-labelDER-strukturIndeholder
-----BEGIN PUBLIC KEY-----SubjectPublicKeyInfo (SPKI)Algoritme-OID + offentlig nøgle (n, e). Standard-"offentlig nøgle" overalt.
-----BEGIN RSA PUBLIC KEY-----PKCS#1 RSAPublicKeyBlot (n, e). Gammel OpenSSL og nogle indlejrede stakke.
-----BEGIN PRIVATE KEY-----PKCS#8 PrivateKeyInfoAlgoritme-OID + privat nøgle. Algoritmeuafhængig container, den moderne standard.
-----BEGIN RSA PRIVATE KEY-----PKCS#1 RSAPrivateKeyn, e, d, p, q, …. Det klassiske OpenSSL-genrsa-output.

Samme nøgle, forskellige indpakninger. Alle fire bokse ovenfor efter Generér indeholder det samme nøglepar — SPKI og PKCS#1 offentlig indeholder identiske n, e; PKCS#8 og PKCS#1 privat indeholder identiske private værdier. Denne side konverterer mellem dem tabsfrit i browseren (dens selvtest laver rundture af konverteringerne). At forveksle formaterne er den enkelte hyppigste årsag til fejl om "ugyldig nøgle", når nøgler indsættes mellem værktøjer.

Krypterede PEM'er (-----BEGIN ENCRYPTED PRIVATE KEY-----) er PKCS#8 med et adgangskodebaseret krypteringslag. Denne side accepterer dem ikke — dekryptér dem offline først (openssl pkcs8 -in enc.pem -out plain.pem).

Almindelige fejl
  • Kryptering af store datamængder med RSA. Ud over den strenge OAEP-størrelsesgrænse er det absurd langsomt. Mønsteret er: generér en tilfældig AES-nøgle, RSA-OAEP-kryptér AES-nøglen, AES-GCM-kryptér dataene, og send begge dele.
  • At sende den private nøgle ud, fordi "det er en test". Eksempelnøglerne indlejret i denne sides vektorer er offentliggjort med vilje — de kan kun nogensinde signere testdata. Egne nøgler er ikke sådan.
  • Verifikation med den private nøgle. Det "virker" normalt matematisk, og nogle værktøjer tillader det, men at distribuere en privat nøgle til verifikatorer ødelægger hele modellen. Verificér med den offentlige nøgle (denne side håndhæver det).
  • At sammenligne signaturer byte for byte for at tjekke kode. PSS (og OAEP) er randomiserede: to korrekte kørsler giver forskellige output. Sammenlign ved at verificere, ikke ved lighed — kun v1.5-signaturer er deterministiske.
  • 1024-bit nøgler "fordi de er hurtigere". De er også inden for rækkevidde for veludstyret faktorisering. Hastighedsargumentet døde med hybridkryptering: RSA kører én gang pr. session, ikke pr. byte.
  • At hardcode en saltlængde, der ikke er hash-længden, for PSS. Verifikatoren skal være enig; hash-længden (denne sides valg og OpenSSL's -sigopt rsa_pss_saltlen:32) er den interoperable standard.
Ofte stillede spørgsmål

Hvorfor fejlede min dekryptering med "forkert nøgle, forkert hash eller beskadiget ciphertext"? OAEP-dekryptering fejler, når en af følgende er tilfældet: det er ikke den matchende private nøgle, hashen afviger fra krypteringssiden, labelen afviger, eller en ciphertext-byte er ændret. Fejlen er bevidst identisk for alle tilfælde — at afsløre, hvilken kontrol der fejlede, er i sig selv et padding-oracle-læk.

Kan jeg få den offentlige nøgle ud af den private nøgle? Ja — de private formater indeholder også n og e. Siden viser begge efter Generér; OpenSSL gør det med openssl pkey -in priv.pem -pubout.

Hvorfor 65537 som eksponent? Det er et primtal, har kun to 1-bit (hurtig potensopløftning) og er stort nok til at undgå de lav-eksponent-angreb, der rammer e=3. Det har været standardvalget siden 1990'erne; en "underlig" eksponent betyder normalt en svag eller ikke-standard nøgle.

Er RSA død på grund af kvantecomputere? Ikke endnu — der findes ingen maskine, der kan køre Shors algoritme på et 2048-bit modul. Men data, der skal forblive hemmelige ind i 2030'erne og senere, migreres allerede; PQC-hybridskemaer er det tekniske svar.

Og openssl rsautl? Det er den forældede forgænger til pkeyutl. Den bruger som standard v1.5-krypteringspolstring — endnu en grund til, at den blev udfaset.