密碼學的基礎:X.690和對應的BER CER DER編碼

簡介

之前我們講到了優秀的數據描述語言ASN.1,很多協議標準都是使用ASN.1來進行描述的。對於ASN.1來說,只定義了數據的描述是不夠的,它還規定了消息是如何被編碼的,從而可以在不同的機器中進行通訊。

ASN.1支援一系列的編碼規則,比如BER,DER,CER等。而X.690就是一個ITU-T的標準,它裡面包含了一些對ASN.1進行編碼的規則。

有人要問了,那麼什麼是ITU-T呢?

ITU-T的全稱是International Telecommunication Union Telecommunication Standardization Sector,也就是國際電聯電信標準化部門,主要用來協調電信和資訊通訊技術標準。

X.690主要包含了Basic Encoding Rules (BER),Canonical Encoding Rules (CER)和Distinguished Encoding Rules (DER)這三種編碼規則。

接下來,我們來看下這些編碼規則的實現細節。

BER編碼

BER的全稱是Basic Encoding Rules,它是最早的編碼規則,使用Tag-Length-Value(TLV)的格式對所有資訊進行編碼。

在BER中,每個數據元素都被編碼為類型標識符、長度描述、實際數據元素,以及可選的內容結束標記,如下所示:

類型標識符|長度|實際數據|內容結束標記
—|—|—|—|—
Type|Length|Value|只用在不確定長度的情況

所有的編碼都是以位元組為單位的。

類型標識符

ASN.1的類型有下面幾種,下表列出了ASN.1中類型和對應的十進位的關係:

type名稱 基礎類型還是組合類型 Number(十進位)
End-of-Content (EOC) 基礎類型 0
BOOLEAN 基礎類型 1
INTEGER 基礎類型 2
BIT STRING 兩者皆可 3
OCTET STRING 兩者皆可 4
NULL 基礎類型 5
OBJECT IDENTIFIER 基礎類型 6
Object Descriptor 兩者皆可 7
EXTERNAL 組合類型 8
REAL (float) 基礎類型 9
ENUMERATED 基礎類型 10
EMBEDDED PDV 組合類型 11
UTF8String 兩者皆可 12
RELATIVE-OID 基礎類型 13
TIME 基礎類型 14
Reserved 15
SEQUENCE and SEQUENCE OF 組合類型 16
SET and SET OF 組合類型 17
NumericString 兩者皆可 18
PrintableString 兩者皆可 19
T61String 兩者皆可 20
VideotexString 兩者皆可 21
IA5String 兩者皆可 22
UTCTime 兩者皆可 23
GeneralizedTime 兩者皆可 24
GraphicString 兩者皆可 25
VisibleString 兩者皆可 26
GeneralString 兩者皆可 27
UniversalString 兩者皆可 28
CHARACTER STRING 組合類型 29
BMPString 組合類型 30
DATE 基礎類型 31
TIME-OF-DAY 基礎類型 32
DATE-TIME 基礎類型 33
DURATION 基礎類型 34
OID-IRI 基礎類型 35
RELATIVE-OID-IRI 基礎類型 36

以上就是ASN.1中的類型和對應的值。接下來我們看下這些類型是怎麼進行編碼的。

ASN.1都是以位元組為單位的,一個位元組是8bits,其中7-8bits表示的是Tag class。2個bits可以表示4種class,如下:

class value 描述
Universal 0 ASN.1的native類型
Application 1 該類型僅對一種特定應用程式有效
Context-specific 2 這種類型依賴於context
Private 3

6bit表示的是這個類型是簡單類型還是組合類型,簡單類型用0,組合類型用1。

還剩下5個bits,可以表示32個不同的值,但是對於ASN.1來說,它的類型是超出32範圍的,所以這5個bits只用來表示0-30的值的範圍。如下所示:

如果想要表示超出30範圍的值,那麼可以使用兩個byte,如下:

前面一個byte的1-5bits全部用1表示,後面一個byte的第8bit用1表示,剩下的7個bits用來表示真實的值。

長度

type編碼之後就是length編碼,length編碼有兩種格式,一種是確定長度的length,一種是不確定長度的length。

如果數據的長度是可預見的,那麼我們就可以使用確定長度的編碼形式,如果長度是不確定的,那麼就可以使用不確定長度的編碼形式。

我們看下不同類型的長度編碼形式:

首先,如果是確定長度,並且長度比較短的情況下,那麼在8bit位設置為0,剩下的7個bits可以表示0-127範圍的長度情況。

如果長度超過了127,那麼可以在8bit設置為1,並且剩下的7個bits表示的是後面存儲長度的byte個數,byte個數的範圍是(1-126)。

如果是非固定長度,那麼在8bit位設置為1,剩下的7bits設置為0。

所有bits都設置為1的是保留值。

在非固定長度的情況下,如果內容結束之後,需要額外附加一個byte表示的End-of-Contents,用來表示非固定長度編碼已經結束了。

內容

Contents是跟在長度後面的byte欄位,Contents的長度可以為0,表示沒有Contents內容。

總體來看BER編碼,通過類型+長度+具體的內容欄位來組成的。

CER編碼和DER編碼

CER的全稱是Canonical Encoding Rules, DER的全稱是Distinguished Encoding Rules,這兩個編碼都是從BER衍生過來的,他們都是BER的變體。

為什麼會有這兩個變體呢?首先考慮一下BER的定義,BER是Basic Encoding Rules,它是一個非常基礎的編碼規則,在很多情況下並沒有提供具體的編碼實現規則,所以需要具體的實現者自行對基礎協議進行擴展。

那麼對應的,如果一個實現者聲明自己是支援BER編碼協議的,那麼就意味著這個實現者需要支援所有BER可能的變體編碼規則。

BER為我們提供了一個基礎標準,它的可擴展性很強,雖然我們在架構或者系統應用中經常提到可擴展性,但是在某些情況下,可變性和可擴展性並不是我們所希望的。比如在密碼學中,我們希望編碼規則的是固定的。這樣的情況就需要用到CER和DER編碼。

CER和DER編碼都是BER的擴展,他們和BER相比,只規定了一種具體的編碼規則,所以他們的確定性更強。

CER和DER相比,CER使用的是不確定長度的格式,而DER使用的是確定長度的格式。這就是說DER中始終包含了前導的長度資訊,而CER則是是用一個位元組的內容結束符來表示編碼的結束。

另外,在DER中,Bit string, octet string 和受限的字元串必須使用基礎類型,不能使用組合類型。

DER被廣泛使用在數字證書中,比如X.509。

總結

以上就是X.690和對應的BER CER DER編碼詳解,看完本篇文章,你又多會了一門語言,oh yeah!

更多內容請參考 //www.flydean.com/47-x690-ber-cer-der/

最通俗的解讀,最深刻的乾貨,最簡潔的教程,眾多你不知道的小技巧等你來發現!

歡迎關注我的公眾號:「程式那些事」,懂技術,更懂你!