BER kodovani

BER je specifikovano v doporuceni X.209. Noveji pak v doporucenich X.690 a X.691.

Cilem BER kodovani je prevest zapis z ASN.1, tj. z podoby dobre citelne pro cloveka, do podoby (kodovani) vhodne pro komunikaci mezi pocitaci.

Problemem kazdeho kodovani je interpretace jednotlivych bitu v kazdem bajtu. BER specifikuje poradi v jakem se interpretuji jednotlive bity v kazdem bajtu tak, ze nejvyznamnejsi bit je vlevo:

Data se v BER koduji vzdy ve strukture tri poli: typ dat, delka a hodnota:


 

Pole typu dat

Pole typu dat je pro tagy mensi nez 31 jednobajtove. Pro vetsi tagy je vicebajtove. V praxi je snaha pouzivat v maximalni mire tato pole jednobajtova.

Pole typu dat v sobe nese soucet tri hodnot, ze kterych je slozeno:

Univerzalni typy zacinaji od nuly, aplikacni od 64 (sestnactkove 40), Content-specific od 128 (8016) a privatni od 192 (C016). Neni-li typ jednoduchy, tj. je-li strukturovany, pak se musi pricist jeste bit J/K, tj. pricte se 32 desitkove, resp. 20 sestnactkove.

Nektere hodnoty univerzalnich tagu jsou uvedeny v nasledujici tabulce:
 
Typ
Tag desitkove
Tag sestnactkove
Poznamka
BOOLEAN 1 1 Nabyva hodnot TRUE a FALSE
INTEGER 2 2 Cela kladna i zaporna cisla a nula
BIT STRING 3 3 Retezec bitu - muze byt zadan binarne nebo hexadecimalne. 
Priklad: 'A98A'H nebo '1010100110001010'B
OCTET STRING 4 4 Retezec bajtu (blize nespecifikovany)
NULL 5 5 Prazny typ 
OBJECT IDENTIFIER 6 6 Identifikator objektu (viz samostatna kapitola)
REAL 9 6 {Mantisa,Base,Exponent} = M x BE 
ENUMERATED 10 A Vycet hodnot (nemusi byt usporadany)
SEQUENCE a SEQUENCE OF 16 10 Usporadana posloupnost prvku. SEQUENCE OF muze byt  i prazdna.
SET a SET OF 17 11 Mnozina prvku (neusporadana). SET OF muze byt i prazdna. 
PrintableString 19 13 0-9 a-z A-Z mezera ' ( ) + , - . / : = ?
T61String 20 14 TeleText podle doporuceni T.61 
Krome PrintableString obsahuje: 
87 102 103 106 107 SPACE DELETE
IA5String 22 16 ASCII, tj. krome znaku PrintableString obsahuje: SPACE DELETE
UTCTime 23 17 Cas ve formatu UTC. 
Napr. 19851106210627.3-0500 
vyjadruje 11.6.1985 v 21:06:27,3 kde mistni casove pasmo je 5 hodin zapadne od Grenwiche.
VisibleString 26 1A
Priklad:   SEQUENCE  ma hodnotu tagu sestnactkove 10, ale sekvence neni jednoduchy typ (sklada se z  prvku tvorici sekvenci), tj. je strukturovanym typem (pripocitavame tedy 2016), takze vysledna hodnota pole typu je:
1016 + 2016 = 3016.

Nazvy typu zacinaji velkym pismenem. Nazvy typu ktere jsou tvoreny pouze velkymi pismeny (vsechna pismena jsou velka jako napr. INTEGER) jsou klicovymi slovy jazyka ASN.1 a nesmi se pouzit v jinem vyznamu.

Pole delka dat

 Delku je mozne principialne vyjadrit dvema zpusoby: Pri explicitni definici delky datoveho pole rozlisujeme opet dva pripady:
  1. Datove pole se sklada z 0 az 127 bajtu, pak pole delky je jednobajtove (tzv. kratka forma pole delka).
  2. Datove pole je delsi nez 127 bajtu (tzv. dlouha forma pole delka).
Pro pripad explicitni definice delky je vyznam jednotlivych bitu v poli delky znazornen na nasledujicim obrazku.


Poznamka k obrazku: 126x8=1008

Priklad: Datove pole je dlouhe 2 bajty, pak v poli delka muze byt (sestnactkove):

Pole data

Pole data pak obsahuje vlastni data.

Priklady

 Priklad 1: Vyjadrete cele cislo 13 v kodovani BER.
Cele cislo je univeralniho typu INTEGER, ktery je nestrukturovany. Urceme hodnotu jednotlivych poli: Vysledek je 02 01 0D nebo 02 81 01 0D atd. (V Kodovani DER je pripustne pouze 02 01 0D). Retezec 02010D se pak prenasi pocitacovou siti a kazdy vi (i hacker), ze se jedna o trinactku.

Pomoci naseho konvertoru si provedte kontrolu:

  1. Retezec 02 01 0D pomoci mysi vyberte z tohoto textu a ulozte do schranky.
  2. V dalsim okne si zobrazte konvertor z http://info.pvt.net/ssl.htm   a do jeho vstupniho pole ze schranky vlozte retezec 02 01 0D.
  3. V tomto textu retezce vyjadrujeme setnactkove ale v praxi se pouziva spise kodovani Base64 (napr. az budete pitvat bezpecne maily). Proto nejprve zvolime "Kodovani Base64 (vstup se zadava hexadecimalne)" a prevedme nas retezec do kodovani Base64.
  4. Na vysledek z predchoziho bodu pouzijeme volbou "PEM -> ASN.1 & DER (DER je vypsan hexadecimalne)" opravdu zjistime, ze 02 01 0D je cele cislo 0D (trinact):

  5.  INTEGER           :0D
        02 01 0d
Cviceni 1:     Pomoci konvertoru overte, ze 02 81 01 0D je take trinact.

Cviceni 2:      Jak bude v kodovani BER retezec KOTE? (Napr: 16 04 4B 4F 54 45)

Priklad 2: Nyni muzeme pristoupit ke slozitejsimu prikladu. V kodovani BER vyjadrete jednu polozku z kartoteky zamestnancu firmy kapitalista.cz. Tato firma ma kazdeho zamestnance popsaneho na karte skladajici se ze ctyr polozek:
 
prijmeni IA5String
jmeno IA5String
sex BOOLEAN
znamosti BOOLEAN

Jenze kazda karta je v sekvenci techto polozek. Vyjadreno tabulkou
 
prijmeni IA5String
jmeno IA5String
sex BOOLEAN
znamosti BOOLEAN
 
SEQUENCE
 
Coz v ASN.1 vyjadrime:  
Zamestnanec ::= SEQUENCE { 
    prijmeni    IA5string, 
    jmeno        IA5string, 
    sex            BOOLEAN, 
    znamosti    BOOLEAN } 
 

V ASN.1 se v praxi zapis Typu Zamestnanec   pise "elegantneji":
Zamestnanec ::= SEQUENCE {
    prijmeni    Prijmeni,
    jmeno        Jmeno,
    sex             Sex,
    znamosti    Znamosti }
Kde
   Prijmeni    ::= IA5string,
    Jmeno      ::= IA5string,
    Sex           ::=  BOOLEAN,
    Znamosti  ::=   BOOLEAN }

Misto typu SEQUENCE by se asi mel pouzit typ SEQUENCE OF, protoze kartoteka muze byt i prazna (kdyz vsechny zamestnance propustime).
Takze kartu v kodovani BER pro zamestnance: Bobek Bob TRUE (Sex) FALSE (Znamosti) bychom v BER konstruovali  zevnitr (od jednoduchych typu):

Vysledek si muzeme overit pomoci konvertoru. Opet provedeme nejprve konverzi do Base64 (vstup se zadava hexadecimalne) a posleze konverzi PEM -> ASN.1 & DER. Vysledek z konvertoru je:

 SEQUENCE
    30 12
  IA5STRING         :Bobek
     16 05 42 6f 62 65 6b
  IA5STRING         :Bob
     16 03 42 6f 62
  BOOLEAN           :1
     01 01 01
  BOOLEAN           :0
     01 01 00

Jak je v BER-kodovani kodovan prazny typ?

05 00  (jedine pripustne v DER)
05 81 00
atd.
 
 

Jak je to s kodovanim typu INTEGER?

Typ INTEGER se koduje binarne tak, jak je to bezne, tj. nejvyznamejsi bit nastaveny na 1 signalizuje zaporne cislo.

Priklady kodovani celych cisel:
 
 
Hodnota  BER-kodovani 
0 02 01 00
12710 = 7F16 02 01 7F
12810 = 8016 02 02 00 80
25610 = 10016 02 02 01 00
-12810  (10016-8016=8016 02 01 80
-12910   (1000016-8116=FF7F16) 02 02 FF 7F
 
 

Vycet

Pomoci typu INTEGER lze vytvorit vycet tak, ze se jednotlive hodnoty pojmenuji identifikatory. V kulatych zavorkach za identifikatorem hodnoty je pak uvedena pojmenovana hodnota.

Obecne: INTEGER [{identifikator-1 (hodnota-1) ... identifikator-n (hodnota-n)}]

Priklad:
Barva ::= INTEGER {cervena(1) modra(2) bila (3)}
 

Priklad z definice certifikatu X.509:
Version :== {v1988(0)}

Certificate :== SEQUENCE {
        ...
        version   Version   DEFAULT   v1988
        ...}

Tim se chce sdelit, ze identifikator version je typu INTEGER a neni-li polozka uvedena, pak se pouzije hodnota 0.
 
 

Typy SEQUENCE, SEQUENCE OF, SET a SET OF

Jedna se o struktrurovane typy (k tagu se pripocitava 2016).

Slovo OF v obou pripadech vyjadruje, ze posloupnost (resp. mnozina) muze byt i prazna.

V posloupnosti (SEQUENCE) zalezi na poradi prvku, v mnozine (SET) nikoliv.

Syntaxe SEQUENCE o n prvcich je:

SEQUENCE  {
        [identifikator-1] Typ-1 [{OPTIONAL | DEFAULT hodnota-1}],
        ...
        [identifikator-n] Typ-n [{OPTIONAL | DEFAULT hodnota-n}] }

Syntaxe SEQUENCE OF, SET a SET OF je obdobna, pouze s tim rozdilem, ze slovo SEQUENCE je nahrazeno slovy SEQUENCE OF, resp. SET, resp. SET OF.

Slovo OPTIONAL vyjadruje, ze prvek je volitelny (nepovinny). Slovo DEFAULT nasledovane hodnotou pak urcuje, ze v pripade kdy prvek neni uveden, pak se pouzije implicitni hodnota.
 

UTCTime

cas se vyjadruje v jednom z nasledujicich tvaru: Znak Z specifikuje, ze se jedna o GMT. Za znamenkem + ci - je casovy posun mistni casove zony.

Napr.: 19851106210627.3-0500
vyjadruje 11.6.1985 v 21:06:27,3 kde mistni casove pasmo je 5 hodin zapadne od Grenwiche.
V BER-kodovani se UTCTime zpravidla koduje v ASCII, tj. uvedeny cas bude:
31 39 38 35 31 31 30 36 32 31 30 36 32 37 2e 33 2d 30 35 30 30
(pro orientaci: 0=3016, 1=3116 , ...,  minus je 2d).
Musime jeste doplnit typ (UTCTime ma 1716 ) a delka je 1516 cili:
17 15 31 39 38 35 31 31 30 36 32 31 30 36 32 37 2e 33 2d 30 35 30 30
 
 

Bit string

Retezec bitu se zpravidla zprava doplnuje vyplni tvorenou binarnimi nulami tak, aby jeho delka byla nasobkem 8 (tj. doplni se na bajty).

Zleva se pred retezec doplni bajt binarne vyjadrujici o kolik bitu byl retezec doplnen.

Priklad:
 
Retezec 01101110 11 
Zprava doplnen sesti binarnimi nulami 01101110 11000000
Preveden na bajty (vyjadreno sestnactkove) 6E C0
Zleva doplnen bajtem vyjadrujicim delku vyplne (6) 06 6E C0
BER kodovani (03 je tag pro bit string, 03 je i delka) 03 03 06 6E C0

Identifikace objektu