Udviklere

Hvad er Base64-kodning? Sådan virker det, med eksempler

8 min læsning

Base64-kodning er en måde at repræsentere alle former for data, tekst eller binære data, med kun 64 udskrivbare ASCII-tegn, så data kan overleve systemer, der kun er bygget til at håndtere almindelig tekst sikkert. Det er hverken kryptering eller komprimering. Det er en reversibel formatomdannelse, som alle kan vende om i ét trin.

Hvad Base64-kodning egentlig gør

Base64 tager rå bytes og udtrykker dem igen med et fast alfabet på 64 symboler: A-Z, a-z, 0-9 samt + og /. Hver 3 bytes input bliver til præcis 4 Base64-tegn, så det kodede output ender med at være omkring 33 % større end det, der gik ind.

Det sidste punkt snubler folk over hele tiden, så det er værd at sige ligeud: Base64 gør data større, ikke mindre, og det bruger ingen form for nøgle. Hvis du “koder” et password i Base64 og gemmer det sådan, har du ikke beskyttet det. Enhver med fem sekunder og en teksteditor kan afkode det tilbage til klartekst igen. Base64 løser et transportproblem, nemlig om en byte-sekvens kan overleve at blive sat ind i et tekstfelt, en URL eller en JSON-streng, ikke et sikkerhedsproblem. Skal noget holdes hemmeligt, er det hashing og kryptering, der klarer den opgave, og ingen af delene har noget med Base64 at gøre.

Sådan virker det: kodning af “Man” bit for bit

Navnet afslører det: Base64 er en baseomregning. Almindelige bytes er base 256, altså 8 bit hver med 256 mulige værdier. Base64 omgrupperer de samme bit i 6-bit-grupper, og hver 6-bit-gruppe, med 64 mulige værdier fra 0 til 63, svarer til ét tegn i alfabetet.

Tag teksten “Man”. De tre ASCII-byteværdier er M=77, a=97, n=110. Skrevet i binær ser det sådan ud:

TegnByteværdiBinær (8 bit)
M7701001101
a9701100001
n11001101110

Sæt alle 24 bit sammen i rækkefølge: 010011010110000101101110. Del nu den samme bit-streng op i fire grupper af 6, helt uden hensyn til de oprindelige byte-grænser:

010011 | 010110 | 000101 | 101110

Hver 6-bit-gruppe er bare et tal mellem 0 og 63. Omregn dem til decimaltal, og slå hver af dem op i Base64-alfabetet:

6-bit-gruppeDecimalværdiBase64-tegn
01001119T
01011022W
0001015F
10111046u

Læs tegnene i rækkefølge, og “Man” bliver til “TWFu”. Der er ikke noget magisk ved det: 3 bytes, altså 24 bit, deles præcist op i 4 grupper af 6 bit, og 24 kan deles med både 8 og 6 uden rest. Det er netop grunden til, at forholdet mellem input og output altid lander på 3 bytes ind, 4 tegn ud.

Padding: hvorfor nogle Base64-strenge ender på =

Den rene 3-byte-gruppering ovenfor virker kun, når din inputlængde er et multiplum af 3. Det er det meste almindelige tekst ikke, så Base64 har brug for en måde at signalere, at den sidste gruppe er kort. Det er det, udfyldningstegnet = gør.

InputBytesBase64-outputHvorfor
”M”1TQ==1 byte kan ikke fylde en 3-byte-gruppe, så den giver kun 2 rigtige tegn, udfyldt med ==
”Ma”2TWE=2 bytes giver 3 rigtige tegn, udfyldt med ét =
”Man”3TWFu3 bytes fylder gruppen præcist, 4 tegn, ingen udfyldning nødvendig

Hvert = du ser i slutningen af en Base64-streng, er bare udfyldning, der markerer, hvor mange bit der manglede i den sidste gruppe. Det bærer ingen data i sig selv.

Hvor du faktisk støder på Base64

Base64 dukker op overalt, hvor binære eller specielle data skal igennem en kanal, der kun forstår tekst. Nogle konkrete eksempler:

HTTP Basic Authentication. Login-oplysningerne user:pass1234 kodes til dXNlcjpwYXNzMTIzNA== og sendes i headeren som Authorization: Basic dXNlcjpwYXNzMTIzNA==. Sådan fungerer Basic Auth bogstaveligt talt, og det er samtidig en god påmindelse om, at Basic Auth ikke giver nogen reel beskyttelse i sig selv (se ovenfor), medmindre den kører over HTTPS.

Indlejring af strukturerede data i en payload eller URL. Et JSON-objekt som {"id":42,"active":true} bliver til eyJpZCI6NDIsImFjdGl2ZSI6dHJ1ZX0=, en flad streng uden anførselstegn eller krøllede parenteser, der skal escapes, og som trygt kan puttes ind i en URL-forespørgselsparameter eller et andet JSON-felt.

Data-URL’er. CSS og HTML kan indlejre et lille billede direkte med data:image/png;base64,iVBORw0K... i stedet for en separat filanmodning, hvilket er grunden til, at man en gang imellem ser en tyk klump Base64 ligge inde i et stylesheet.

E-mail-vedhæftninger. MIME, formatet e-mail bruger til vedhæftninger, blev designet for årtier siden til tekstsikker transport, så binære filer bliver Base64-kodet, før de sys ind i beskeden.

JWT-tokens. Et JSON Web Token er tre Base64url-segmenter adskilt af punktummer: header.payload.signature. Payload-segmentet er bare Base64url-kodet JSON, så en almindelig Base64/Base64url-dekoder, som den nedenfor, afslører det uden videre. Det er ikke en dedikeret JWT-dekoder, den afkoder bare det segment, du indsætter.

To eksempler mere, gode til at tjekke enhver dekoder, du sidder og arbejder med:

“Hello, World!” kodes til SGVsbG8sIFdvcmxkIQ==.

“café” kodes til Y2Fmw6k=. Det er værd at stoppe op ved: “café” har 4 bogstaver, men é fylder 2 bytes i UTF-8, så strengen reelt er 5 bytes, ikke 4, og Base64 arbejder på bytes, aldrig på bogstaver. Samme logik gælder en emoji som ”🚀”, der alene fylder 4 UTF-8-bytes og kodes til 8J+agA==. Ser du et Base64-output, der er længere, end du forventede ud fra det synlige antal tegn, er flerbyte-UTF-8 næsten altid grunden.

Kod eller afkod din egen tekst

Skriv i et af de to værktøjer nedenfor. Alt kører lokalt i din browser, intet sendes til en server.

Base64-koder
Gratis, ingen tilmelding, virker på alle enheder.
Åbn hele værktøjet

Almindelige fejl og specialtilfælde

At behandle Base64 som kryptering. Det er værd at gentage klart: Base64 er ikke en sikkerhedsforanstaltning. Den har ingen nøgle, den er fuldt reversibel af design, og at bruge den som beskyttelse af et password, en token eller personoplysninger er et reelt anti-mønster, ikke en lille teknikalitet. Skal noget forblive hemmeligt, skal det krypteres. Base64 er ikke det lag, der gør det.

Standard Base64 er ikke URL-sikker. Tegnene +, / og = kan blive ødelagt eller skabe tvetydighed inde i en URL, en forespørgselsstreng eller et filnavn. Det er grunden til, at en separat variant kaldet Base64url findes, som bytter + og / ud med - og _, og ofte dropper udfyldning helt. Ser du en Base64-lignende streng i en URL eller en JWT uden +, uden / og uden =, er det derfor: det er den URL-sikre variant, ikke en anden kodning.

Mellemrum eller manglende udfyldning ødelægger en afkodning. Strenge afkodere kan afvise en streng med vildfarne linjeskift, mellemrum eller et udfyldningstegn, der er blevet klippet af undervejs. Ryd strengen op først, hvis en afkodning fejler uventet.

Flerbyte-UTF-8 gør output større, end man forventer. Som vist ovenfor med “café” og ”🚀” koder Base64 bytes, ikke synlige bogstaver. Bogstaver med accenter, CJK-tekst og emoji fylder alle mere end én byte hver i UTF-8, så den kodede længde afspejler byte-antallet, ikke det man ville få ved at tælle tegn på skærmen.

Dobbeltkodning ved et uheld. Kører man en allerede Base64-kodet streng gennem koderen igen, får man et ekstra lag Base64 viklet rundt om det første. Afkoder man den én gang, får man bare den oprindelige kodede streng tilbage, stadig volapyk, ikke det rigtige indhold. Ligner en afkodning volapyk, så prøv at afkode den en gang til, før du antager, at strengen er ødelagt.

Ofte stillede spørgsmål

Er Base64 det samme som kryptering? Nej. Base64 er en reversibel kodning helt uden nøgle. Alle kan afkode den i ét trin uden specialværktøj eller særlig viden. Skal data holdes hemmelige, skal du bruge rigtig kryptering. Base64 ændrer kun repræsentationen, ikke fortroligheden.

Hvorfor ser Base64-output længere ud end den oprindelige tekst? Fordi det bytter 8-bit bytes ud med 6-bit tegn, så 3 bytes input altid bliver til 4 tegn output, en fast stigning på omkring 33 %. Den overhead er prisen for at kunne repræsentere vilkårlige bytes med et lille, tekstsikkert alfabet.

Hvad betyder =-tegnene i slutningen af en Base64-streng? De er udfyldning, tilføjet når inputlængden ikke er et rent multiplum af 3 bytes. Ét = betyder, at den sidste gruppe manglede én byte, == betyder, den manglede to. De koder ingen egentlige data, de markerer bare, hvor input sluttede.

Hvorfor har nogle Base64-strenge i URL’er eller JWT’er hverken +, / eller =? De bruger Base64url, en variant bygget specifikt til URL’er, filnavne og tokens som JWT. Den bytter de to tegn, der giver problemer i en URL, + og /, ud med - og _, og springer som regel udfyldning helt over.

Kan jeg afkode en JWT med en Base64-dekoder? Du kan afkode header- og payload-segmenterne, da begge bare er Base64url-kodet JSON adskilt af punktummer. Indsæt et af segmenterne, ikke hele tokenet og ikke signatur-delen, i en Base64/Base64url-dekoder for at læse claims indeni.

Base64KodningWebudviklingAPI'er
Base64-koder
Prøv det nu selv med hele værktøjet.
Prøv nu
Relaterede værktøjer