RSA-kryptering / -dekryptering

Generer RSA-nøkkelpar i nettleseren, krypter og dekrypter med RSA-OAEP, signer med RSA-PSS eller PKCS#1 v1.5, og konverter nøkler mellom SPKI-, PKCS#8- og PKCS#1-PEM-formatene. Alt kjøres lokalt med WebCrypto-motoren — ingen nøkkel eller melding forlater denne siden.
Hva RSA er til: små meldinger og signaturer, ikke store datamengder. RSA krypterer høyst k−2·hashLen−2 byte per kall (190 byte for en 2048-bit-nøkkel med SHA-256) og er ~1000× tregere enn AES. Reelle systemer bruker hybridkryptering: RSA innpakker en tilfeldig AES-nøkkel, og AES krypterer dataene (se AES-verktøyet). Denne siden finnes for læring, testing og interoperabilitetskontroller.
Modulstørrelse:
Hash: Etikett:
PKCS#1 v1.5-kryptering er bevisst ikke implementert: den har ingen chiffertekstintegritet og faller for padding-oracle-angrep (Bleichenbacher). OAEP er den eneste krypteringsmodusen en ny design bør bruke.
Ordning: Hash:
Ordning: Hash:
Hvor mye kan ett RSA-kall bære? OAEP-meldingsgrense = nøkkelbyte − 2×hash-byte − 2:
ModulSHA-256SHA-384SHA-512
1024-bit62 byte30 byte0 byte
2048-bit190 byte126 byte62 byte
3072-bit318 byte254 byte190 byte
4096-bit446 byte382 byte318 byte
Signaturer har ingen meldingsgrense — meldingen hashes først; selve signaturen er alltid nøyaktig nøkkelstørrelsen (256 byte for 2048-bit).
Nøkkelstyrke og levetid (NIST SP 800-57 Part 1 Rev. 5): 1024-bit ble forbudt for ny bruk etter 2013; 2048-bit er minimum i dag og forblir akseptabelt til 2030; 3072-bit og større er det komfortable valget for 2031 og senere. 8192-bit fungerer her, men generering kan ta et minutt eller mer i nettleseren og gir sikkerhet ingen trenger i dag — foretrekk 3072/4096.
OpenSSL-interoperabilitet — PEM-ene denne siden produserer, går rundt 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: legg til -sigopt rsa_padding_mode:pss -sigopt rsa_pss_saltlen:32 til begge dgst-kallene. Formatkonvertering av nøkkel: openssl rsa -in key.pem -RSAPublicKey -out pubkey.pem gjør SPKI ↔ PKCS#1 på disk; denne siden gjør det i nettleseren.
Selvtest
Kjører sidemotoren mot uavhengige ankere: nøkkelgenerering ved tre modulstørrelser, OAEP-kryptering og -dekryptering, PSS- og PKCS#1 v1.5-signering og -verifisering på tvers av hasher, en deterministisk v1.5-signaturvektor byte for byte (generert av en uavhengig, innebygd implementasjon), en fast OAEP-chiffertekst og PSS-signatur produsert av OpenSSL som denne siden må dekryptere og verifisere (interoperabilitet mellom implementasjoner), PEM-formatkonverteringer, og negative tester (manipulert signatur og feil nøkkel må feile). Ingenting sendes noe sted.
RSA-kryptering og signaturer forklart fra bunnen av
Kort fortalt: RSA er offentlig-nøkkel-kryptografi — hvem som helst kan kryptere til mottakeren med den offentlige nøkkelen eller verifisere signaturer, men bare den private nøkkelen kan dekryptere eller signere — og sikkerheten hviler på at det å faktorisere et 2048-bit tall i to primtall er utenfor rekkevidde for enhver datamaskin som finnes.
Hva RSA faktisk beregner

To primtall og en fellesdør. En RSA-nøkkel starter som to store tilfeldige primtall p og q; produktet n (modulen, derav «2048-bit-nøkkel») publiseres i den offentlige nøkkelen sammen med en eksponent e (nesten alltid 65537). Den private nøkkelen er d, den modulære inversen av e − beregnet fra p og q — pluss snarveier avledet fra primtallene som gjør operasjoner med privat nøkkel opptil 4× raskere.

Kryptering og signering er samme eksponentiering. Å kryptere en meldingsblokk m betyr å beregne me mod n; dekryptering er cd mod n. Å signere en forhåndsformatert blokk med den private eksponenten og verifisere med den offentlige er samme operasjon i motsatt retning. Alt annet på denne siden — OAEP, PSS, PKCS#1 — handler om å formatere blokken trygt, slik at rå eksponentiering aldri blir eksponert.

Hvorfor den er treg. Én RSA-operasjon med en 2048-bit-nøkkel koster i størrelsesorden en million ganger mer CPU enn å kryptere én blokk med AES. Derfor bruker TLS RSA (eller ECC) bare til å bli enige om en tilfeldig AES-nøkkel, og bytter deretter. Samme regel gjelder for alt man bygger: RSA for nøkkelen, AES for dataene.

Nøkkelstørrelse. Modullengden er sikkerhetsknappen: 1024-bit er brutt etter retningslinjene (faktorisering er innen rekkevidde for stater), 2048-bit ≈ 112-bit symmetrisk styrke, 3072-bit ≈ 128-bit, 15360-bit ville tilsvare en 256-bit symmetrisk nøkkel. Merknad om post-kvante: Shors algoritme bryter RSA helt på en stor kvantedatamaskin — en grunn til å holde nøkkelenes levetid begrenset.

OAEP: den eneste krypteringsfyllingen som bør brukes

Problemet med rå RSA. Lærebok-RSA (me mod n på den rå meldingen) er deterministisk og formbar: identiske meldinger krypteres likt, en angriper kan multiplisere en chiffertekst med krypteringen av 2 for å doble klarteksten, og korte meldinger faller i meet-in-the-middle. Den må aldri brukes direkte.

Hva OAEP gjør. OAEP (PKCS#1 v2, RFC 8017) blander meldingen med et tilfeldig frø gjennom et hash-basert Feistel-nettverk før eksponentiering. Resultatet: kryptering er randomisert (samme klartekst gir en ny chiffertekst hver gang — kjør OAEP-eksempelet to ganger og sammenlign), manipulering oppdages ved dekryptering, og meldingen må få plass i modulen med rom for hashen — grensen k−2·hashLen−2 i tabellen over.

Etiketten. En valgfri offentlig streng bundet inn i fyllingen. Begge sider må oppgi den identiske etiketten, ellers mislykkes dekrypteringen — som AAD i AES-GCM lar den binde chifferteksten til en kontekst (et filnavn, en algoritme-id). Tom er normalt.

PKCS#1 v1.5-kryptering er bevisst fraværende. Fyllingen fra 1993 har ingen integritet og lekker informasjon gjennom dekrypteringsfeilens oppførsel (Bleichenbachers angrep fra 1998 gjør en padding-oracle om til fullstendig dekryptering med noen millioner laget chiffertekster; det bryter fortsatt reelle systemer som ROBOT, 2017). WebCrypto nekter å implementere den; det gjør ikke denne siden heller.

PSS vs PKCS#1 v1.5-signaturer

Signer = hash, deretter fyll, deretter eksponentier. Begge ordningene hasher meldingen (SHA-256/384/512 her), formaterer digesten til en blokk og bruker den private eksponenten. Verifisering formaterer blokken på nytt med den offentlige nøkkelen og sammenligner. Forskjellen ligger i formateringen:

SkjemaBlokkinnholdEgenskaper
RSASSA-PKCS1-v1_5digest + digest-info-header, deterministiskHver signatur av samme melding er byte-identisk (sjekk selvtesten: v1.5-vektoren er fast). Universell støtte i eldre systemer: X.509-sertifikater, JWT RS*, TLS før 1.3. Ingen kjent forfalskning når verifiseringen er implementert korrekt.
RSA-PSSdigest + tilfeldig salt med hash-lengde, MGF1-maskeringRandomisert — hver signatur er forskjellig. Bevist sikker i random-oracle-modellen; kreves i TLS 1.3-sertifikater og nyere protokoller. Verifisereren må kjenne saltlengden (denne siden bruker hash-lengde, den vanlige standarden).

Hva velge. Nye design: PSS. Interoperabilitet med eksisterende sertifikater, JWT-er (RS256) eller eldre parter: v1.5. Begge er trygge som signaturordninger — v1.5-katastrofehistorien handler om *kryptering*-fylling, en annen konstruksjon til tross for det like navnet.

PKCS#1 vs PKCS#8 vs SPKI: hvorfor samme nøkkel har fire PEM-er

PEM er bare base64-innpakket DER. En PEM-fil er en etikett pluss base64 av en DER-struktur (binær ASN.1). Etiketten forteller hvilken struktur det er — og det er hele forskjellen mellom de fire formatene denne siden genererer:

PEM-etikettDER-strukturInneholder
-----BEGIN PUBLIC KEY-----SubjectPublicKeyInfo (SPKI)Algoritme-OID + offentlig nøkkel (n, e). Den vanlige «offentlige nøkkelen» overalt.
-----BEGIN RSA PUBLIC KEY-----PKCS#1 RSAPublicKeyRå (n, e). Eldre OpenSSL og enkelte innebygde stacker.
-----BEGIN PRIVATE KEY-----PKCS#8 PrivateKeyInfoAlgoritme-OID + privat nøkkel. Algoritmeuavhengig beholder, den moderne standarden.
-----BEGIN RSA PRIVATE KEY-----PKCS#1 RSAPrivateKeyn, e, d, p, q, …. Den klassiske OpenSSL-genrsa-utdata.

Samme nøkkel, ulike innpakninger. Alle fire boksene ovenfor etter generering inneholder samme nøkkelpar — SPKI og PKCS#1 offentlig inneholder identiske n og e; PKCS#8 og PKCS#1 privat inneholder identiske private verdier. Denne siden konverterer mellom dem tapsfritt i nettleseren (selvtesten gjør konverteringene rundt). Å forveksle formatene er den vanligste årsaken til «ugyldig nøkkel»-feil når nøkler limes inn mellom verktøy.

Krypterte PEM-er (-----BEGIN ENCRYPTED PRIVATE KEY-----) er PKCS#8 med et passordbasert krypteringslag. Denne siden godtar dem ikke — dekrypter dem frakoblet (openssl pkcs8 -in enc.pem -out plain.pem) først.

Vanlige feil
  • Kryptering av store datamengder med RSA. Utover den strenge OAEP-størrelsesgrensen er det absurd tregt. Mønsteret er: generer en tilfeldig AES-nøkkel, RSA-OAEP-krypter AES-nøkkelen, AES-GCM-krypter dataene, og send begge delene.
  • Å sende den private nøkkelen fordi «det er bare en test». Eksempelnøklene innebygd i vektorene på denne siden er publisert med vilje — de kan bare signere testdata. Egne nøkler er ikke slik.
  • Verifisering med den private nøkkelen. Det «fungerer» vanligvis matematisk, og noen verktøy tillater det, men å distribuere en privat nøkkel til verifiserere ødelegger hele modellen. Verifiser med den offentlige nøkkelen (denne siden håndhever det).
  • Å sammenligne signaturer byte for byte for å sjekke kode. PSS (og OAEP) er randomiserte: to korrekte kjøringer gir ulike resultater. Sammenlign ved å verifisere, ikke ved likhet — bare v1.5-signaturer er deterministiske.
  • 1024-bit-nøkler «fordi de er raskere». De er også innen rekkevidde for godt finansierte faktoriseringsangrep. Hastighetsargumentet døde med hybridkryptering: RSA kjøres én gang per økt, ikke per byte.
  • Hardkoding av en saltlengde som ikke er hash-lengde for PSS. Verifiseren må være enig; hash-lengde (denne sidens valg og OpenSSLs -sigopt rsa_pss_saltlen:32) er den interoperable standarden.
Ofte stilte spørsmål

Hvorfor mislyktes dekrypteringen med «feil nøkkel, feil hash eller skadet chiffertekst»? OAEP-dekryptering mislykkes når en av følgende er sann: det er ikke den tilhørende private nøkkelen, hashen avviker fra krypteringssiden, etiketten er forskjellig, eller en byte i chifferteksten er endret. Feilmeldingen er bevisst lik for alle tilfeller — å avsløre hvilken kontroll som feilet, er i seg selv en padding-oracle-lekkasje.

Kan jeg få den offentlige nøkkelen fra den private? Ja — de private formatene inneholder også n og e. Denne siden viser begge etter generering; OpenSSL gjør det med openssl pkey -in priv.pem -pubout.

Hvorfor 65537 som eksponent? Den er et primtall, har bare to 1-bit (rask eksponentiering), og er stor nok til å unngå lav-eksponent-angrep som rammer e=3. Den har vært standardvalget siden 1990-tallet; en «merkelig» eksponent betyr vanligvis en svak eller ikke-standard nøkkel.

Er RSA død på grunn av kvantedatamaskiner? Ikke ennå — det finnes ingen maskin som kan kjøre Shors algoritme på en 2048-bit modul. Men data som må forbli hemmelige inn i 2030-årene, migreres allerede; PQC-hybridordninger er det tekniske svaret.

Hva med openssl rsautl? Den er den avviklede forløperen til pkeyutl. Den bruker v1.5-krypteringsfylling som standard — enda en grunn til at den ble faset ut.