You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 12 Current »

Base64 i MIME

1. Innledning

Denne artikkelen tar for seg Base64-koding, og hvordan denne brukes i MIME. Base64 og MIME hører til i applikasjonslaget i OSI-modellen, og brukes aktivt i e-post-protokoller. Base64-kodingen har senere blitt brukt videre i en rekke ulike områder, blant annet i kryptering. Det er Internet Engineering Task Force (IETF) som står bak utviklingen av Base64-standarden. Base64 ble først definert i RFC 989, som omhandler “Privacy Enhancement for Internet Electronic Mail”. Kodingen ble her brukt for å gjøre om kryptert data til en printbar/lesbar form.I denne artikkelen bruker vi en nyere definisjon, fra RFC 2045 seksjon 6.8. Det finnes mange variasjoner av Base64, der de 64 tegnene og paddingregler varierer.

2. Ønsket funksjonalitet

Ofte sendes binærdata av ulikt format, og man vil unngå risikoen for at ulike protokoller tolker dataene ulikt. Dersom man streamer bits og bytes over nettverket i råformat, vil man risikere at noen protokoller tror det overføres spesialtegn i bitmønsteret. Dette betyr at når man sender meldinger i rene bits uten å kode dem, vil man ikke ha noen garanti for at ulike protokoller tolker tegnene likt. Ved hjelp av Base64 omformer man binærdata til tekst slik at det blir enklere å sende både epost og html-skjemaer. 

 SMTP har problemer som nevnt over. Punktum er et spesialtegn i protokollen, og betyr “slutt på melding”. Dersom man skriver en epost med punktum, vil bare teksten fram til første punktum sendes, dersom man ikke koder meldingen. Siden SMTP begynte som en rent ASCII-tekstbasert protokoll, slet den med å tolke binærfiler eller tekst i andre språk enn engelsk. Standarder som MIME ble utviklet nettopp for å kode binærfiler for overføring ved SMTP.

MIME er utviklet for at epost skal støtte:

  • Tekst i andre tegnsett enn ASCII

  • Ikke-tekstlige vedlegg; video, bilde eller audio.

  • Komplekse meldinger delt inn i flere deler

  • Header-informasjon i andre tegnsett enn ASCII

Andre funksjoner som er avhengige av MIME

Selv om MIME i hovedsak er utviklet for SMTP, er standardene definert i MIME også viktig for kommunikasjonsprotokoller utenom epost, som HTTP.  Servere setter inn MIME-headere i begynnelsen av enhver web-overføring. Klienter bruker denne mediatype-headeren (MIME type) for å velge riktig visningsprogram for den typen data som er indikert i headeren. Noen av disse visningsprogrammene er innebygd i nettleseren eller webklienten.

3. Virkemåte

Base64 fungerer i praksis på 2 måter: Koding og dekoding.

Under koding, tar man inn en streng eller et bitmønster (vi bruker streng i eksempelet vårt, men den gjøres uansett om til et bitmønster). Utdata fra kodingen, vil være en ny streng, som kun vil inneholde tegn fra oversettelsestabellen som nevnes senere. Denne strengen vil i gjennomsnitt være 33% lengre enn inputstrengen.

Man tar de 6 første bitsene fra et 8-bits tegn, og har dermed 2 bits i rest som blir tatt med i neste gruppe av 6 bits. Slik fortsetter man med hele strengen. Man deler altså inn bitmønster ifra grupper på 8 til grupper på 6, og får en del tegn i tillegg på grunn av en forskyvning av tegnene, derav overheaden på 1/3. Under dekoding tar man inn en kodet Base64-streng, og gjør denne om til klartekst eller binær data. Dette gjøres enkelt nok med å reversere kodingsprosessen.

Oversettelsestabell

For å kunne oversette fra og til Base64, trenger vi en tabell med tallverdier og deres tilhørende tegn i Base64-kodingen. Tegnene i denne tabellen er de eneste tegnene som kan forekomme i en Base64-kodet streng (med unntak av =, men det skal vi se på senere). Merk at ingen av tegnene har noen spesiell mening i SMTP, og data med for eksempel punktum og linjeskift kan da sendes trygt uten misforståelser i protokollen. Merk også at det er 64 ulike tegn, siden Base64 deler opp data i 6 bits om gangen (26=64). 

Omformingstabell - http://www.4dgraphix.com/wp-content/uploads/2015/01/Untitled2.png

Koding til Base64

For å kode en streng til Base64, må vi først finne tallverdier for alle tegnene i strengen. I dette eksempelet, kan vi kode strengen "Data". For å finne tallverdier for tegnene, kan man slå opp i en ASCII- eller UTF-8-tabell. Vi finner da verdiene:

 

Tegn

D

a

t

a

Tallverdi

68

97

116

97

Bitverdi

01000100

01100001

01110100

01100001

 


I tabellen over, har jeg også oversatt tallverdiene til binære tall, noe vi kommer til å trenge nå. Siden Base64 har 64 mulige verdier, trenger vi 6 bytes, ikke 8, for å representere hvert tegn. Vi deler da opp hele bitmønsteret i nye bitmønster med lengde 6:

010001 000110 000101 110100 011000 01

Her ser vi imidlertid at vi får et problem. Bitmønsterets lengde er 32, som ikke går opp i 6. Det man gjør da, er rett og slett å fylle ut resten av det uferdige siste mønsteret med 0-ere:

010001 000110 000101 110100 011000 010000

Det er i tillegg nødvendig at den endelige strengen har en lengde som er delelig på 4 (som oppfylles når antall bytes i input er delelig på 3). For å oppfylle dette kravet, legger vi til såkalt padding, som er at vi legger på 0-bits helt til kravet er oppfylt:

010001 000110 000101 110100 011000 010000 000000 000000

Nå har vi 8 ulike 6-bits mønster, og vi kan da bruke oversettelsestabellen fra forrige seksjon for å få den endelige Base64-strengen:

 

 

Bits

010001

000110

000101

110100

011000

010000

000000

000000

Tallverdi

17

6

5

52

24

16

0

0

Tegn

R

G

F

0

Y

Q

=

=

 

Merk her at vår padding ikke blir til A, selv om den har tallverdien 0. Paddingen har et fast tegn, nemlig =. Den endelige Base64-kodede strengen av Data, blir da RGF0YQ==.

Dekoding fra Base64

Når man skal dekode fra Base64, følger man egentlig bare prosessen for å kode, bare baklengs. For enkelhets skyld, kan vi dekode RGF0YQ==, som ble brukt over. Det første man gjør, er å se på hvert enkelt tegn i strengen, for å så finne den korresponderende tallverdien i oppslagstabellen:

 

 

Tegn

R

G

F

0

Y

Q

=

=

Tallverdi

17

6

5

52

24

16

0

0

Bits

010001

000110

000101

110100

011000

010000

000000

000000

 

Vi kan så dele opp bitmønsteret vi får i 8-bits-grupper:

01000100 01100001 01110100 01100001 00000000 00000000

De 2 padding-tegnene (==) i slutten, sier at de 4 siste tegn kun vil bli gjort om til ett tegn, og vi kan derfor ignorere de 2 siste gruppene. Hadde det vært ett padding-tegn, ville dette betydd at de 4 siste tegnene ville blitt gjort om til 2 tegn. Resten av gruppene kan vi bruke til å oversette til de dekodede tegnene, igjen via en ASCII-/UTF-8-tabell:

 

 

Bitmønster

01000100

01100001

01110100

01100001

Tegn

D

a

t

a

 

Base64-strengen RGF0YQ== blir derfor dekodet til Data.

4. Kilder

RFC 989 - https://tools.ietf.org/html/rfc989

RFC 2045 - https://tools.ietf.org/html/rfc2045#section-6.8

RFC 4648 - https://tools.ietf.org/html/rfc4648



  • No labels