RSA-kryptering / -dekryptering — RSA-OAEP, PSS og PKCS#1 v1.5
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.
1. Generer et nøkkelpar(WebCrypto, lokalt; de fire PEM-formatene produseres samtidig)
Modulstørrelse:
Offentlig nøkkel — SPKI(-----BEGIN PUBLIC KEY-----, det vanlige formatet for «RSA-offentlig nøkkel»)
Offentlig nøkkel — PKCS#1(-----BEGIN RSA PUBLIC KEY-----, bare modul + eksponent)
Privat nøkkel — PKCS#8(-----BEGIN PRIVATE KEY-----, ukryptert; behandle den som et passord)
Privat nøkkel — PKCS#1(-----BEGIN RSA PRIVATE KEY-----, det klassiske OpenSSL-formatet)
Å generere en nøkkel i nettleseren krypterer den ikke. For lagring må den flyttes til et ekte nøkkelhvelv eller krypteres frakoblet.
2. Eller importer en eksisterende nøkkel(lim inn et av de fire PEM-formatene)
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.
4. Signer (krever den private nøkkelen)- PSS (randomisert, moderne) eller PKCS#1 v1.5 (deterministisk, legacy-kompatibel)
Ordning:Hash:
5. Verifiser (krever den offentlige nøkkelen)- lim inn meldingen og signaturen
Ordning:Hash:
Hvor mye kan ett RSA-kall bære?OAEP-meldingsgrense = nøkkelbyte − 2×hash-byte − 2:
Modul
SHA-256
SHA-384
SHA-512
1024-bit
62 byte
30 byte
0 byte
2048-bit
190 byte
126 byte
62 byte
3072-bit
318 byte
254 byte
190 byte
4096-bit
446 byte
382 byte
318 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:
Skjema
Blokkinnhold
Egenskaper
RSASSA-PKCS1-v1_5
digest + digest-info-header, deterministisk
Hver 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-PSS
digest + tilfeldig salt med hash-lengde, MGF1-maskering
Randomisert — 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:
Rå (n, e). Eldre OpenSSL og enkelte innebygde stacker.
-----BEGIN PRIVATE KEY-----
PKCS#8 PrivateKeyInfo
Algoritme-OID + privat nøkkel. Algoritmeuavhengig beholder, den moderne standarden.
-----BEGIN RSA PRIVATE KEY-----
PKCS#1 RSAPrivateKey
n, 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.