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

2022-08-01 21:07:26

簡介

之前我們講到了優秀的資料描述語言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!

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

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

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